combo/combo/manager/forms.py

326 lines
11 KiB
Python

# combo - content management system
# Copyright (C) 2014-2016 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/>.
import re
from django import forms
from django.conf import settings
from django.contrib.auth.models import Group
from django.core.exceptions import ValidationError
from django.template import Template, TemplateSyntaxError
from django.template.loader import TemplateDoesNotExist, get_template
from django.utils.translation import ugettext_lazy as _
from combo.data.models import Page, ParentContentCell, SiteSettings, compile_sub_slug
from .fields import ImageIncludingSvgField
def get_groups_as_choices():
return [(x.id, x.name) for x in Group.objects.all().order_by('name')]
def get_template_name_choices(with_models=False):
def template_exists(template):
try:
get_template(settings.COMBO_PUBLIC_TEMPLATES[template].get('template'))
except TemplateDoesNotExist:
return False
return True
templates = [(x[0], x[1]['name']) for x in settings.COMBO_PUBLIC_TEMPLATES.items()]
templates = [x for x in templates if template_exists(x[0])]
templates.sort(key=lambda x: x[1])
if not with_models or settings.COMBO_PUBLIC_TEMPLATES_ROOT_PAGE is None:
return templates
try:
model_root_page = Page.objects.get(slug=settings.COMBO_PUBLIC_TEMPLATES_ROOT_PAGE)
except Page.DoesNotExist:
return templates
templates.extend([('model_%s' % p.slug, p.title) for p in model_root_page.get_descendants()])
templates.sort(key=lambda x: x[1])
return templates
class PageDuplicateForm(forms.Form):
title = forms.CharField(label=_('New title'), max_length=150, required=False)
class PageExportForm(forms.Form):
with_subpages = forms.BooleanField(label=_('Also export subpages'), required=False)
class PageAddForm(forms.ModelForm):
class Meta:
model = Page
fields = ('title', 'template_name')
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
self.parent = kwargs.pop('parent', None)
super().__init__(*args, **kwargs)
self.fields['template_name'].widget = forms.Select(
choices=get_template_name_choices(with_models=True)
)
self.fields['template_name'].initial = settings.COMBO_DEFAULT_PUBLIC_TEMPLATE
def save(self, *args, **kwargs):
template_name = self.cleaned_data['template_name']
if template_name.startswith('model_'):
try:
model_page = Page.objects.get(slug=template_name[6:])
except Page.DoesNotExist:
pass
else:
# model page, create page by duplication
self.instance = model_page.duplicate(title=self.cleaned_data['title'], parent=self.parent)
if self.instance.pk is None:
# not a model page, create page from form
self.instance = super().save(commit=False, *args, **kwargs)
self.instance.parent = self.parent
self.instance.save()
if self.instance.slug != 'index' or self.parent:
for placeholder in self.instance.get_placeholders(request=self.request):
if not placeholder.acquired:
continue
ParentContentCell.objects.create(page=self.instance, placeholder=placeholder.key, order=0)
return self.instance
class PageRestrictedAddForm(PageAddForm):
class Meta:
model = Page
fields = ('title', 'template_name', 'parent')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
group_ids = [x.id for x in self.request.user.groups.all()]
self.fields['parent'].queryset = Page.objects.filter(subpages_edit_role_id__in=group_ids)
self.fields['parent'].required = True
self.fields['parent'].empty_label = None
def save(self, *args, **kwargs):
self.parent = self.cleaned_data.get('parent')
return super().save(*args, **kwargs)
class PageEditTitleForm(forms.ModelForm):
class Meta:
model = Page
fields = ('title',)
class PageEditSlugForm(forms.ModelForm):
class Meta:
model = Page
fields = ('slug', 'sub_slug')
def clean_slug(self):
value = self.cleaned_data.get('slug')
if self.instance.slug == value:
return value
if Page.objects.filter(slug=value, parent_id=self.instance.parent_id).count() > 0:
raise ValidationError(_('Slug must be unique'), code='unique')
return value
def clean_sub_slug(self):
value = self.cleaned_data.get('sub_slug')
if not value:
return value
try:
compile_sub_slug(value)
except re.error:
raise ValidationError(_('Bad Regular expression.'), code='bad_regex')
return value
class PageEditDescriptionForm(forms.ModelForm):
class Meta:
model = Page
fields = ('description',)
class PageEditPictureForm(forms.ModelForm):
class Meta:
model = Page
fields = ('picture',)
field_classes = {'picture': ImageIncludingSvgField}
class PageVisibilityForm(forms.ModelForm):
class Meta:
model = Page
fields = ('public', 'groups')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['groups'].queryset = Group.objects.order_by('name')
class PageSelectTemplateForm(forms.ModelForm):
class Meta:
model = Page
fields = ('template_name',)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['template_name'].widget = forms.Select(choices=get_template_name_choices())
class PageEditRedirectionForm(forms.ModelForm):
class Meta:
model = Page
fields = ('redirect_url',)
def clean_redirect_url(self):
value = self.cleaned_data.get('redirect_url')
if value:
try:
Template(value)
except TemplateSyntaxError as e:
raise ValidationError(_('syntax error: %s') % e)
return value
def save(self, *args, **kwargs):
page = super().save(*args, **kwargs)
page.redirect_url = page.redirect_url.strip()
page.save()
return page
class PageEditRolesForm(forms.ModelForm):
edit_role = forms.ModelChoiceField(
label=_('Edit Role'), required=False, queryset=Group.objects.all().order_by('name')
)
subpages_edit_role = forms.ModelChoiceField(
label=_('Subpages Edit Role'), required=False, queryset=Group.objects.all().order_by('name')
)
class Meta:
model = Page
fields = (
'edit_role',
'subpages_edit_role',
)
class PageEditIncludeInNavigationForm(forms.ModelForm):
include_in_navigation = forms.BooleanField(label=_('Include in navigation menus'), required=False)
apply_to_subpages = forms.BooleanField(label=_('Apply to subpages'), required=False)
class Meta:
model = Page
fields = []
def __init__(self, *args, **kwargs):
instance = kwargs['instance']
initial = kwargs.pop('initial', {})
initial['include_in_navigation'] = not instance.exclude_from_navigation
super().__init__(initial=initial, *args, **kwargs)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if self.cleaned_data['apply_to_subpages']:
subpages = self.instance.get_descendants(include_myself=True)
subpages.update(exclude_from_navigation=bool(not self.cleaned_data['include_in_navigation']))
else:
self.instance.exclude_from_navigation = not self.cleaned_data['include_in_navigation']
self.instance.save()
return self.instance
class CellVisibilityForm(forms.Form):
visibility = forms.ChoiceField(
label=_('Visibility'),
choices=[
('all', _('Everybody')),
('logged', _('Logged users')),
('unlogged', _('Unlogged users')),
('groups-any', _('Users with one of these groups')),
('groups-none', _('Users with none of these groups')),
],
)
groups = forms.MultipleChoiceField(label=_('Groups'), required=False, choices=get_groups_as_choices)
def __init__(self, *args, **kwargs):
self.instance = instance = kwargs.pop('instance')
initial = kwargs.get('initial')
initial['groups'] = [x.id for x in instance.groups.all()]
if instance.public:
if instance.restricted_to_unlogged:
initial['visibility'] = 'unlogged'
else:
initial['visibility'] = 'all'
else:
initial['visibility'] = 'logged'
if initial['groups']:
if instance.restricted_to_unlogged:
initial['visibility'] = 'groups-none'
else:
initial['visibility'] = 'groups-any'
super().__init__(*args, **kwargs)
def save(self):
if self.cleaned_data['visibility'] == 'all':
self.instance.public = True
self.instance.restricted_to_unlogged = False
self.instance.groups.clear()
elif self.cleaned_data['visibility'] == 'logged':
self.instance.public = False
self.instance.restricted_to_unlogged = False
self.instance.groups.clear()
elif self.cleaned_data['visibility'] == 'unlogged':
self.instance.public = True
self.instance.restricted_to_unlogged = True
self.instance.groups.clear()
elif self.cleaned_data['visibility'] == 'groups-any':
self.instance.public = False
self.instance.restricted_to_unlogged = False
self.instance.groups.set(self.cleaned_data['groups'])
elif self.cleaned_data['visibility'] == 'groups-none':
self.instance.public = False
self.instance.restricted_to_unlogged = True
self.instance.groups.set(self.cleaned_data['groups'])
self.instance.save()
return self.instance
class SiteImportForm(forms.Form):
site_file = forms.FileField(label=_('Site Export File'))
class SiteExportForm(forms.Form):
pages = forms.BooleanField(label=_('Pages'), required=False, initial=True)
cartography = forms.BooleanField(label=_('Maps'), required=False, initial=True)
pwa = forms.BooleanField(label=_('Mobile Application (PWA)'), required=False, initial=True)
assets = forms.BooleanField(label=_('Assets'), required=False, initial=True)
asset_files = forms.BooleanField(label=_('Assets Files'), required=False, initial=False)
payment = forms.BooleanField(label=_('Online Payment'), required=False, initial=True)
class SiteSettingsForm(forms.ModelForm):
class Meta:
model = SiteSettings
fields = '__all__'