2016-10-13 15:55:15 +02:00
|
|
|
import json
|
2016-11-28 15:46:58 +01:00
|
|
|
import time
|
2016-09-23 17:02:17 +02:00
|
|
|
from collections import OrderedDict
|
|
|
|
|
|
|
|
from django.conf import settings
|
2016-11-28 15:46:58 +01:00
|
|
|
from django.forms import CharField, ModelForm, ValidationError
|
2016-09-26 17:23:08 +02:00
|
|
|
from django.forms.models import ModelChoiceField
|
2016-09-23 15:23:02 +02:00
|
|
|
from django.forms.widgets import HiddenInput
|
2016-12-01 12:25:02 +01:00
|
|
|
from django.utils.translation import ugettext_lazy as _
|
2016-10-13 15:55:15 +02:00
|
|
|
from shapely.geometry.geo import mapping
|
2016-09-23 15:23:02 +02:00
|
|
|
|
2016-10-13 15:55:15 +02:00
|
|
|
from c3nav.mapdata.models import Package
|
2016-09-26 17:23:08 +02:00
|
|
|
from c3nav.mapdata.permissions import get_unlocked_packages
|
2016-09-23 15:23:02 +02:00
|
|
|
|
|
|
|
|
2016-11-27 23:51:44 +01:00
|
|
|
class MapitemFormMixin(ModelForm):
|
2016-10-16 15:17:30 +02:00
|
|
|
def __init__(self, *args, request=None, **kwargs):
|
2016-09-26 17:23:08 +02:00
|
|
|
self.request = request
|
2016-09-23 15:23:02 +02:00
|
|
|
super().__init__(*args, **kwargs)
|
2016-10-13 15:55:15 +02:00
|
|
|
creating = not self.instance.pk
|
2016-09-23 15:23:02 +02:00
|
|
|
|
2016-10-13 15:55:15 +02:00
|
|
|
# disable name on non-direct editing
|
|
|
|
if not creating and not settings.DIRECT_EDITING:
|
2016-09-26 17:23:08 +02:00
|
|
|
self.fields['name'].disabled = True
|
2016-10-13 15:55:15 +02:00
|
|
|
|
2016-11-28 15:46:58 +01:00
|
|
|
if creating:
|
|
|
|
self.fields['name'].initial = hex(int(time.time()*1000000))[2:]
|
2016-10-16 15:56:24 +02:00
|
|
|
|
2016-10-13 15:55:15 +02:00
|
|
|
# restrict package choices and field_name
|
|
|
|
if not creating:
|
2016-09-26 17:23:08 +02:00
|
|
|
if not settings.DIRECT_EDITING:
|
|
|
|
self.fields['package'].widget = HiddenInput()
|
|
|
|
self.fields['package'].disabled = True
|
2016-10-13 15:55:15 +02:00
|
|
|
self.initial['package'] = self.instance.package.name
|
2016-09-29 16:33:45 +02:00
|
|
|
elif not settings.DIRECT_EDITING:
|
2016-09-26 17:23:08 +02:00
|
|
|
unlocked_packages = get_unlocked_packages(request)
|
|
|
|
if len(unlocked_packages) == 1:
|
|
|
|
self.fields['package'].widget = HiddenInput()
|
|
|
|
self.fields['package'].initial = next(iter(unlocked_packages))
|
2016-10-13 15:55:15 +02:00
|
|
|
self.fields['package'].disabled = True
|
2016-09-26 17:23:08 +02:00
|
|
|
else:
|
|
|
|
self.fields['package'] = ModelChoiceField(
|
2016-10-13 15:55:15 +02:00
|
|
|
queryset=Package.objects.filter(name__in=unlocked_packages),
|
2016-09-26 17:23:08 +02:00
|
|
|
)
|
2016-10-13 15:55:15 +02:00
|
|
|
self.fields['package'].to_field_name = 'name'
|
|
|
|
|
2016-11-28 15:46:58 +01:00
|
|
|
if 'level' in self.fields:
|
|
|
|
# hide level widget and set field_name
|
|
|
|
self.fields['level'].widget = HiddenInput()
|
|
|
|
self.fields['level'].to_field_name = 'name'
|
|
|
|
if not creating:
|
|
|
|
self.initial['level'] = self.instance.level.name
|
2016-10-13 15:55:15 +02:00
|
|
|
|
2016-12-04 11:43:12 +01:00
|
|
|
if 'crop_to_level' in self.fields:
|
|
|
|
# set field_name
|
|
|
|
self.fields['crop_to_level'].to_field_name = 'name'
|
|
|
|
if not creating and self.instance.crop_to_level is not None:
|
|
|
|
self.initial['crop_to_level'] = self.instance.crop_to_level.name
|
|
|
|
self.fields['crop_to_level'].queryset = self.fields['crop_to_level'].queryset.order_by('altitude')
|
|
|
|
|
2016-12-01 12:25:02 +01:00
|
|
|
if 'levels' in self.fields:
|
|
|
|
# set field_name
|
|
|
|
self.fields['levels'].to_field_name = 'name'
|
2016-12-04 01:49:49 +01:00
|
|
|
self.fields['levels'].queryset = self.fields['levels'].queryset.order_by('altitude')
|
2016-12-01 12:25:02 +01:00
|
|
|
|
2016-11-28 15:46:58 +01:00
|
|
|
if 'geometry' in self.fields:
|
|
|
|
# hide geometry widget
|
|
|
|
self.fields['geometry'].widget = HiddenInput()
|
|
|
|
if not creating:
|
|
|
|
self.initial['geometry'] = json.dumps(mapping(self.instance.geometry), separators=(',', ':'))
|
2016-10-13 15:55:15 +02:00
|
|
|
|
|
|
|
# parse titles
|
|
|
|
self.titles = None
|
|
|
|
if hasattr(self.instance, 'titles'):
|
|
|
|
titles = OrderedDict((lang_code, '') for lang_code, language in settings.LANGUAGES)
|
|
|
|
if self.instance is not None and self.instance.pk:
|
|
|
|
titles.update(self.instance.titles)
|
|
|
|
|
|
|
|
language_titles = dict(settings.LANGUAGES)
|
|
|
|
for language in titles.keys():
|
|
|
|
new_title = self.data.get('title_' + language)
|
|
|
|
if new_title is not None:
|
|
|
|
titles[language] = new_title
|
|
|
|
self.fields['title_' + language] = CharField(label=language_titles.get(language, language),
|
|
|
|
required=False,
|
|
|
|
initial=titles[language].strip(), max_length=50)
|
|
|
|
self.titles = titles
|
|
|
|
|
2016-12-01 12:25:02 +01:00
|
|
|
def clean_levels(self):
|
|
|
|
levels = self.cleaned_data.get('levels')
|
|
|
|
if len(levels) < 2:
|
|
|
|
raise ValidationError(_('Please select at least two levels.'))
|
|
|
|
return levels
|
|
|
|
|
2016-11-28 15:46:58 +01:00
|
|
|
def clean(self):
|
|
|
|
if 'geometry' in self.fields:
|
|
|
|
if not self.cleaned_data.get('geometry'):
|
|
|
|
raise ValidationError('Missing geometry.')
|
|
|
|
|
|
|
|
|
|
|
|
def create_editor_form(mapitemtype):
|
2016-12-04 01:49:49 +01:00
|
|
|
possible_fields = ['name', 'package', 'altitude', 'level', 'intermediate', 'levels', 'geometry',
|
2016-12-04 11:43:12 +01:00
|
|
|
'elevator', 'button', 'crop_to_level']
|
2016-11-28 15:46:58 +01:00
|
|
|
existing_fields = [field for field in possible_fields if hasattr(mapitemtype, field)]
|
2016-10-13 15:55:15 +02:00
|
|
|
|
2016-11-27 23:51:44 +01:00
|
|
|
class EditorForm(MapitemFormMixin, ModelForm):
|
2016-10-13 15:55:15 +02:00
|
|
|
class Meta:
|
2016-11-28 15:46:58 +01:00
|
|
|
model = mapitemtype
|
|
|
|
fields = existing_fields
|
2016-10-13 15:55:15 +02:00
|
|
|
|
2016-11-28 15:46:58 +01:00
|
|
|
mapitemtype.EditorForm = EditorForm
|
2016-10-13 15:55:15 +02:00
|
|
|
|
2016-09-23 17:02:17 +02:00
|
|
|
|
2016-10-15 11:23:27 +02:00
|
|
|
def create_editor_forms():
|
2016-11-28 15:46:58 +01:00
|
|
|
from c3nav.mapdata.models.base import MAPITEM_TYPES
|
|
|
|
for mapitemtype in MAPITEM_TYPES.values():
|
|
|
|
create_editor_form(mapitemtype)
|