nicer indented json encoding now also in rest api
This commit is contained in:
parent
55fc17e872
commit
84bb9ad73a
10 changed files with 62 additions and 40 deletions
|
@ -0,0 +1,15 @@
|
||||||
|
from rest_framework.renderers import JSONRenderer
|
||||||
|
from ..mapdata.utils import json_encoder_reindent
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
|
orig_render = JSONRenderer.render
|
||||||
|
|
||||||
|
|
||||||
|
@wraps(JSONRenderer.render)
|
||||||
|
def nicer_renderer(self, data, accepted_media_type=None, renderer_context=None):
|
||||||
|
if self.get_indent(accepted_media_type, renderer_context) is None:
|
||||||
|
return orig_render(self, data, accepted_media_type, renderer_context)
|
||||||
|
return json_encoder_reindent(lambda d: orig_render(self, d, accepted_media_type, renderer_context), data)
|
||||||
|
|
||||||
|
# Monkey patch for nicer indentation in the django rest framework
|
||||||
|
JSONRenderer.render = nicer_renderer
|
|
@ -1,5 +1,6 @@
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from rest_framework.exceptions import PermissionDenied
|
from rest_framework.exceptions import PermissionDenied
|
||||||
from rest_framework.permissions import BasePermission
|
from rest_framework.permissions import BasePermission
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from ..editor.hosters import get_hoster_for_package
|
from ..editor.hosters import get_hoster_for_package
|
||||||
|
@ -6,24 +7,16 @@ from ..mapdata.models import Level, Package, Source
|
||||||
from .permissions import can_access_package
|
from .permissions import can_access_package
|
||||||
|
|
||||||
|
|
||||||
class BoundsMixin:
|
|
||||||
def to_representation(self, obj):
|
|
||||||
result = super().to_representation(obj)
|
|
||||||
if obj.bottom is not None:
|
|
||||||
result['bounds'] = ((obj.bottom, obj.left), (obj.top, obj.right))
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class LevelSerializer(serializers.ModelSerializer):
|
class LevelSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Level
|
model = Level
|
||||||
fields = ('name', 'altitude', 'package')
|
fields = ('name', 'altitude', 'package')
|
||||||
|
|
||||||
|
|
||||||
class PackageSerializer(BoundsMixin, serializers.ModelSerializer):
|
class PackageSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Package
|
model = Package
|
||||||
fields = ('name', 'home_repo', 'depends')
|
fields = ('name', 'home_repo', 'depends', 'bounds')
|
||||||
|
|
||||||
def to_representation(self, obj):
|
def to_representation(self, obj):
|
||||||
result = super().to_representation(obj)
|
result = super().to_representation(obj)
|
||||||
|
@ -36,10 +29,10 @@ class PackageSerializer(BoundsMixin, serializers.ModelSerializer):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class SourceSerializer(BoundsMixin, serializers.ModelSerializer):
|
class SourceSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Source
|
model = Source
|
||||||
fields = ('name', 'package')
|
fields = ('name', 'package', 'bounds')
|
||||||
|
|
||||||
|
|
||||||
class HosterSerializer(serializers.Serializer):
|
class HosterSerializer(serializers.Serializer):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, url
|
||||||
|
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
from .views import editor as editor_views
|
from .views import editor as editor_views
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
|
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ViewSet
|
from rest_framework.viewsets import ViewSet
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import os
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.files import File
|
from django.core.files import File
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
|
||||||
from rest_framework.decorators import detail_route
|
from rest_framework.decorators import detail_route
|
||||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,12 @@ class Package(models.Model):
|
||||||
def package(self):
|
def package(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bounds(self):
|
||||||
|
if self.bottom is None:
|
||||||
|
return None
|
||||||
|
return ((float(self.bottom), float(self.left)), (float(self.top), float(self.right)))
|
||||||
|
|
||||||
def tofile(self):
|
def tofile(self):
|
||||||
data = OrderedDict()
|
data = OrderedDict()
|
||||||
data['name'] = self.name
|
data['name'] = self.name
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import json
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
@ -26,11 +24,7 @@ class Source(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bounds(self):
|
def bounds(self):
|
||||||
return ((self.bottom, self.left), (self.top, self.right))
|
return ((float(self.bottom), float(self.left)), (float(self.top), float(self.right)))
|
||||||
|
|
||||||
@property
|
|
||||||
def jsbounds(self):
|
|
||||||
return json.dumps(((float(self.bottom), float(self.left)), (float(self.top), float(self.right))))
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fromfile(cls, data, package, name):
|
def fromfile(cls, data, package, name):
|
||||||
|
|
|
@ -3,6 +3,7 @@ import json
|
||||||
from django.core.management.base import CommandError
|
from django.core.management.base import CommandError
|
||||||
|
|
||||||
from ..models import Level, Package, Source
|
from ..models import Level, Package, Source
|
||||||
|
from ..utils import json_encoder_reindent
|
||||||
|
|
||||||
|
|
||||||
class ObjectCollection:
|
class ObjectCollection:
|
||||||
|
@ -93,25 +94,5 @@ class ObjectCollection:
|
||||||
print('- Added dependency: '+depname)
|
print('- Added dependency: '+depname)
|
||||||
|
|
||||||
|
|
||||||
def _preencode(data, magic_marker):
|
|
||||||
if isinstance(data, dict):
|
|
||||||
data = data.copy()
|
|
||||||
for name, value in tuple(data.items()):
|
|
||||||
if name in ('bounds', ):
|
|
||||||
data[name] = magic_marker+json.dumps(value)+magic_marker
|
|
||||||
else:
|
|
||||||
data[name] = _preencode(value, magic_marker)
|
|
||||||
return data
|
|
||||||
elif isinstance(data, (tuple, list)):
|
|
||||||
return tuple(_preencode(value, magic_marker) for value in data)
|
|
||||||
else:
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def json_encode(data):
|
def json_encode(data):
|
||||||
magic_marker = '***JSON_MAGIC_MARKER***'
|
return json_encoder_reindent(json.dumps, data, indent=4)+'\n'
|
||||||
test_encode = json.dumps(data)
|
|
||||||
while magic_marker in test_encode:
|
|
||||||
magic_marker += '*'
|
|
||||||
result = json.dumps(_preencode(data, magic_marker), indent=4)
|
|
||||||
return result.replace('"'+magic_marker, '').replace(magic_marker+'"', '')+'\n'
|
|
||||||
|
|
29
src/c3nav/mapdata/utils.py
Normal file
29
src/c3nav/mapdata/utils.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def _preencode(data, magic_marker):
|
||||||
|
if isinstance(data, dict):
|
||||||
|
data = data.copy()
|
||||||
|
for name, value in tuple(data.items()):
|
||||||
|
if name in ('bounds', ):
|
||||||
|
data[name] = magic_marker+json.dumps(value)+magic_marker
|
||||||
|
else:
|
||||||
|
data[name] = _preencode(value, magic_marker)
|
||||||
|
return data
|
||||||
|
elif isinstance(data, (tuple, list)):
|
||||||
|
return tuple(_preencode(value, magic_marker) for value in data)
|
||||||
|
else:
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def json_encoder_reindent(method, data, *args, **kwargs):
|
||||||
|
magic_marker = '***JSON_MAGIC_MARKER***'
|
||||||
|
test_encode = json.dumps(data)
|
||||||
|
while magic_marker in test_encode:
|
||||||
|
magic_marker += '*'
|
||||||
|
result = method(_preencode(data, magic_marker), *args, **kwargs)
|
||||||
|
if type(result) == str:
|
||||||
|
return result.replace('"'+magic_marker, '').replace(magic_marker+'"', '')
|
||||||
|
else:
|
||||||
|
magic_marker = magic_marker.encode()
|
||||||
|
return result.replace(b'"'+magic_marker, b'').replace(magic_marker+b'"', b'')
|
Loading…
Add table
Add a link
Reference in a new issue