326 lines
11 KiB
Python
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__'
|