add Location.details_display()
This commit is contained in:
parent
ba3e1e485e
commit
949b88389e
8 changed files with 114 additions and 78 deletions
|
@ -1,17 +1,15 @@
|
|||
import mimetypes
|
||||
from collections import namedtuple
|
||||
from functools import wraps
|
||||
from operator import attrgetter
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.db.models import FieldDoesNotExist, Model, Prefetch
|
||||
from django.db.models import Prefetch
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.cache import get_conditional_response
|
||||
from django.utils.http import quote_etag
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import get_language, get_language_info
|
||||
from django.utils.translation import get_language
|
||||
from rest_framework.decorators import detail_route, list_route
|
||||
from rest_framework.exceptions import NotFound, ValidationError
|
||||
from rest_framework.mixins import RetrieveModelMixin
|
||||
|
@ -19,7 +17,7 @@ from rest_framework.response import Response
|
|||
from rest_framework.viewsets import GenericViewSet, ReadOnlyModelViewSet, ViewSet
|
||||
|
||||
from c3nav.mapdata.models import AccessRestriction, Building, Door, Hole, LocationGroup, MapUpdate, Source, Space
|
||||
from c3nav.mapdata.models.access import AccessPermission, AccessRestrictionMixin
|
||||
from c3nav.mapdata.models.access import AccessPermission
|
||||
from c3nav.mapdata.models.geometry.level import LevelGeometryMixin
|
||||
from c3nav.mapdata.models.geometry.space import POI, Area, Column, LineObstacle, Obstacle, SpaceGeometryMixin, Stair
|
||||
from c3nav.mapdata.models.level import Level
|
||||
|
@ -301,78 +299,7 @@ class LocationViewSet(RetrieveModelMixin, GenericViewSet):
|
|||
if isinstance(location, LocationRedirect):
|
||||
return redirect('../' + location.target.slug + '/display/')
|
||||
|
||||
result = location.serialize(geometry=True)
|
||||
|
||||
display = [
|
||||
(str(_('Type')), str(location.__class__._meta.verbose_name)),
|
||||
(str(_('ID')), str(location.pk)),
|
||||
]
|
||||
|
||||
for lang, title in sorted(location.titles.items(), key=lambda item: item[0] != get_language()):
|
||||
language = _('Title ({lang})').format(lang=get_language_info(lang)['name_translated'])
|
||||
display.append((language, title))
|
||||
|
||||
display.append((str(_('Slug')), str(location.get_slug())))
|
||||
|
||||
if isinstance(location, Level):
|
||||
display.append((str(_('short label')), location.short_label))
|
||||
|
||||
if isinstance(location, LevelGeometryMixin):
|
||||
display.append((str(_('Level')), {'slug': location.level.get_slug(), 'title': location.level.title}))
|
||||
|
||||
if isinstance(location, SpaceGeometryMixin):
|
||||
display.append((str(_('Space')), {'slug': location.space.get_slug(), 'title': location.space.title}))
|
||||
|
||||
if isinstance(location, LocationGroup):
|
||||
display.append((str(_('Category')), location.category.title))
|
||||
|
||||
if isinstance(location, AccessRestrictionMixin):
|
||||
display.append((str(_('Access Restriction')),
|
||||
location.access_restriction_id and location.access_restriction.title))
|
||||
|
||||
groupcategories = {}
|
||||
if isinstance(location, SpecificLocation):
|
||||
for group in location.groups.all():
|
||||
groupcategories.setdefault(group.category, []).append(group)
|
||||
|
||||
for category, groups in sorted(groupcategories.items(), key=lambda item: item[0].priority, reverse=True):
|
||||
display.append((category.title, tuple(
|
||||
{'slug': group.get_slug(), 'title': group.title}
|
||||
for group in sorted(groups, key=attrgetter('priority'), reverse=True)
|
||||
)))
|
||||
|
||||
model: Model = location.__class__
|
||||
for name in ('can_search', 'can_describe', 'color', 'outside', 'base_altitude', 'height', 'default_height',
|
||||
'priority'):
|
||||
try:
|
||||
field = model._meta.get_field(name)
|
||||
except FieldDoesNotExist:
|
||||
continue
|
||||
|
||||
value = getattr(location, name)
|
||||
if isinstance(value, bool):
|
||||
value = _('Ja') if value else _('Nein')
|
||||
display.append((str(field.verbose_name), value and str(value)))
|
||||
|
||||
editor_url = None
|
||||
if isinstance(location, Level):
|
||||
editor_url = reverse('editor.levels.detail', kwargs={'pk': location.pk})
|
||||
elif isinstance(location, Space):
|
||||
editor_url = reverse('editor.spaces.detail', kwargs={'level': location.level_id, 'pk': location.pk})
|
||||
elif isinstance(location, Area):
|
||||
editor_url = reverse('editor.areas.edit', kwargs={'space': location.space_id, 'pk': location.pk})
|
||||
elif isinstance(location, POI):
|
||||
editor_url = reverse('editor.pois.edit', kwargs={'space': location.space_id, 'pk': location.pk})
|
||||
elif isinstance(location, LocationGroup):
|
||||
editor_url = reverse('editor.locationgroups.edit', kwargs={'pk': location.pk})
|
||||
|
||||
result = {
|
||||
'editor_url': editor_url,
|
||||
'display': display,
|
||||
'geometry': result['geometry'],
|
||||
}
|
||||
|
||||
return Response(result)
|
||||
return Response(location.details_display())
|
||||
|
||||
@list_route(methods=['get'])
|
||||
@api_etag(permissions=False)
|
||||
|
|
|
@ -89,6 +89,13 @@ class AccessRestrictionMixin(SerializableMixin, models.Model):
|
|||
result['access_restriction'] = self.access_restriction_id
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['display'].extend([
|
||||
(str(_('Access Restriction')), self.access_restriction_id and self.access_restriction.title),
|
||||
])
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def qs_for_request(cls, request, allow_none=False):
|
||||
return cls.objects.filter(cls.q_for_request(request, allow_none=allow_none))
|
||||
|
|
|
@ -3,7 +3,7 @@ from collections import OrderedDict
|
|||
from django.core.cache import cache
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import get_language
|
||||
from django.utils.translation import get_language, get_language_info
|
||||
|
||||
from c3nav.mapdata.fields import JSONField
|
||||
from c3nav.mapdata.models import MapUpdate
|
||||
|
@ -32,6 +32,14 @@ class SerializableMixin(models.Model):
|
|||
result['id'] = self.pk
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
return {
|
||||
'display': [
|
||||
(str(_('Type')), str(self.__class__._meta.verbose_name)),
|
||||
(str(_('ID')), str(self.pk)),
|
||||
]
|
||||
}
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return self._meta.verbose_name + ' ' + str(self.id)
|
||||
|
@ -57,6 +65,13 @@ class TitledMixin(SerializableMixin, models.Model):
|
|||
result['title'] = self.title
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
for lang, title in sorted(self.titles.items(), key=lambda item: item[0] != get_language()):
|
||||
language = _('Title ({lang})').format(lang=get_language_info(lang)['name_translated'])
|
||||
result['display'].append((language, title))
|
||||
return result
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
lang = get_language()
|
||||
|
|
|
@ -88,6 +88,11 @@ class GeometryMixin(SerializableMixin):
|
|||
(int(math.ceil(self.maxx)), int(math.ceil(self.maxy))))
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['geometry'] = format_geojson(mapping(self.geometry), round=False)
|
||||
return result
|
||||
|
||||
def get_shadow_geojson(self):
|
||||
pass
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ from operator import attrgetter, itemgetter
|
|||
import numpy as np
|
||||
from django.db import models
|
||||
from django.db.models import F
|
||||
from django.urls import reverse
|
||||
from django.utils.text import format_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from scipy.sparse.csgraph._shortest_path import dijkstra
|
||||
|
@ -43,6 +44,11 @@ class LevelGeometryMixin(GeometryMixin):
|
|||
result['level'] = self.level_id
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['display'].insert(3, (str(_('Level')), {'slug': self.level.get_slug(), 'title': self.level.title}))
|
||||
return result
|
||||
|
||||
@property
|
||||
def subtitle(self):
|
||||
base_subtitle = super().subtitle
|
||||
|
@ -96,6 +102,15 @@ class Space(LevelGeometryMixin, SpecificLocation, models.Model):
|
|||
result['height'] = None if self.height is None else float(str(self.height))
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['display'].extend([
|
||||
(str(_('height')), self.height),
|
||||
(str(_('outside only')), str(_('yes') if self.outside else _('no'))),
|
||||
])
|
||||
result['editor_url'] = reverse('editor.spaces.detail', kwargs={'level': self.level_id, 'pk': self.pk})
|
||||
return result
|
||||
|
||||
|
||||
class Door(LevelGeometryMixin, AccessRestrictionMixin, models.Model):
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.text import format_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
@ -52,6 +53,11 @@ class SpaceGeometryMixin(GeometryMixin):
|
|||
self.geometry if force else self.get_changed_geometry()
|
||||
))
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['display'].insert(3, (str(_('Space')), {'slug': self.space.get_slug(), 'title': self.space.title}))
|
||||
return result
|
||||
|
||||
def register_delete(self):
|
||||
space = self.space
|
||||
changed_geometries.register(space.level_id, space.geometry.intersection(self.geometry))
|
||||
|
@ -88,6 +94,11 @@ class Area(SpaceGeometryMixin, SpecificLocation, models.Model):
|
|||
result = super()._serialize(**kwargs)
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['editor_url'] = reverse('editor.areas.edit', kwargs={'space': self.space_id, 'pk': self.pk})
|
||||
return result
|
||||
|
||||
|
||||
class Stair(SpaceGeometryMixin, models.Model):
|
||||
"""
|
||||
|
@ -168,6 +179,11 @@ class POI(SpaceGeometryMixin, SpecificLocation, models.Model):
|
|||
verbose_name_plural = _('Points of Interest')
|
||||
default_related_name = 'pois'
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['editor_url'] = reverse('editor.pois.edit', kwargs={'space': self.space_id, 'pk': self.pk})
|
||||
return result
|
||||
|
||||
|
||||
class Hole(SpaceGeometryMixin, models.Model):
|
||||
"""
|
||||
|
|
|
@ -6,6 +6,7 @@ from operator import attrgetter, itemgetter
|
|||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.db.models import Prefetch
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from shapely.geometry import JOIN_STYLE, box
|
||||
|
@ -88,6 +89,16 @@ class Level(SpecificLocation, models.Model):
|
|||
result['default_height'] = float(str(self.default_height))
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['display'].insert(3, (str(_('short label')), self.short_label))
|
||||
result['display'].extend([
|
||||
(str(_('outside only')), self.base_altitude),
|
||||
(str(_('default height')), self.default_height),
|
||||
])
|
||||
result['editor_url'] = reverse('editor.levels.detail', kwargs={'pk': self.pk})
|
||||
return result
|
||||
|
||||
def _render_space_ground(self, svg, space):
|
||||
areas_by_color = {}
|
||||
for area in space.areas.all():
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from collections import OrderedDict
|
||||
from contextlib import suppress
|
||||
from operator import attrgetter
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Prefetch
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.text import format_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
@ -57,6 +59,11 @@ class LocationSlug(SerializableMixin, models.Model):
|
|||
result['slug'] = self.get_slug()
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['display'].insert(2, (str(_('Slug')), str(self.get_slug())))
|
||||
return result
|
||||
|
||||
@cached_property
|
||||
def order(self):
|
||||
return (-1, 0)
|
||||
|
@ -94,6 +101,14 @@ class Location(LocationSlug, AccessRestrictionMixin, TitledMixin, models.Model):
|
|||
result['can_describe'] = self.can_search
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['display'].extend([
|
||||
(str(_('can be searched')), str(_('yes') if self.can_search else _('no'))),
|
||||
(str(_('can describe')), str(_('yes') if self.can_describe else _('no')))
|
||||
])
|
||||
return result
|
||||
|
||||
def get_slug(self):
|
||||
if self.slug is None:
|
||||
code = self.LOCATION_TYPE_CODES.get(self.__class__.__name__)
|
||||
|
@ -139,6 +154,21 @@ class SpecificLocation(Location, models.Model):
|
|||
result['groups'] = groups
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
|
||||
groupcategories = {}
|
||||
for group in self.groups.all():
|
||||
groupcategories.setdefault(group.category, []).append(group)
|
||||
|
||||
for category, groups in sorted(groupcategories.items(), key=lambda item: item[0].priority):
|
||||
result['display'].insert(3, (category.title, tuple(
|
||||
{'slug': group.get_slug(), 'title': group.title}
|
||||
for group in sorted(groups, key=attrgetter('priority'), reverse=True)
|
||||
)))
|
||||
|
||||
return result
|
||||
|
||||
@property
|
||||
def subtitle(self):
|
||||
groups = tuple(self.groups.all())
|
||||
|
@ -230,6 +260,16 @@ class LocationGroup(Location, models.Model):
|
|||
result['locations'] = tuple(obj.pk for obj in getattr(self, 'locations', ()))
|
||||
return result
|
||||
|
||||
def details_display(self):
|
||||
result = super().details_display()
|
||||
result['display'].insert(3, (str(_('Category')), self.category.title))
|
||||
result['display'].extend([
|
||||
(str(_('color')), self.color),
|
||||
(str(_('priority')), self.priority),
|
||||
])
|
||||
result['editor_url'] = reverse('editor.locationgroups.edit', kwargs={'pk': self.pk})
|
||||
return result
|
||||
|
||||
@property
|
||||
def title_for_forms(self):
|
||||
attributes = []
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue