Skip to content

Commit

Permalink
Merge branch 'master-qgis_server' into add-widget-link-kartoza#153
Browse files Browse the repository at this point in the history
  • Loading branch information
boney-bun committed Sep 19, 2017
2 parents 8235fd2 + 9064c11 commit a8a8abd
Show file tree
Hide file tree
Showing 25 changed files with 1,252 additions and 196 deletions.
370 changes: 244 additions & 126 deletions geonode/api/api.py

Large diffs are not rendered by default.

168 changes: 153 additions & 15 deletions geonode/api/resourcebase_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################

import json
import re

from django.core.urlresolvers import resolve
from django.db.models import Q
from django.http import HttpResponse
from django.conf import settings
from django.template.response import TemplateResponse
from tastypie import http
from tastypie.bundle import Bundle

from tastypie.constants import ALL, ALL_WITH_RELATIONS
from tastypie.resources import ModelResource
Expand All @@ -38,12 +43,13 @@

from tastypie.utils.mime import build_content_type

from geonode import get_version
from geonode import get_version, qgis_server, geoserver
from geonode.layers.models import Layer
from geonode.maps.models import Map
from geonode.documents.models import Document
from geonode.base.models import ResourceBase
from geonode.base.models import HierarchicalKeyword
from geonode.utils import check_ogc_backend

from .authorization import GeoNodeAuthorization

Expand Down Expand Up @@ -569,6 +575,31 @@ class Meta(CommonMetaApi):
class LayerResource(CommonModelApi):

"""Layer API"""
links = fields.ListField(
attribute='links',
null=True,
use_in='all',
default=[])
if check_ogc_backend(qgis_server.BACKEND_PACKAGE):
default_style = fields.ForeignKey(
'geonode.api.api.StyleResource',
attribute='qgis_default_style',
null=True)
styles = fields.ManyToManyField(
'geonode.api.api.StyleResource',
attribute='qgis_styles',
null=True,
use_in='detail')
elif check_ogc_backend(geoserver.BACKEND_PACKAGE):
default_style = fields.ForeignKey(
'geonode.api.api.StyleResource',
attribute='default_style',
null=True)
styles = fields.ManyToManyField(
'geonode.api.api.StyleResource',
attribute='styles',
null=True,
use_in='detail')

def format_objects(self, objects):
"""
Expand All @@ -585,31 +616,138 @@ def format_objects(self, objects):
formatted_obj = model_to_dict(obj, fields=values)
# add the geogig link
formatted_obj['geogig_link'] = obj.geogig_link
# add Link link
link_fields = [
'extension',
'link_type',
'name',
'mime',
'url'
]
links = []
for l in obj.link_set.all():
formatted_link = model_to_dict(l, fields=link_fields)
links.append(formatted_link)

formatted_obj['links'] = links
# provide style information
bundle = self.build_bundle(obj=obj)
formatted_obj['default_style'] = self.default_style.dehydrate(
bundle, for_list=True)

if self.links.use_in == 'all' or self.links.use_in == 'list':
formatted_obj['links'] = self.dehydrate_links(
bundle)
# Add resource uri
formatted_obj['resource_uri'] = self.get_resource_uri(bundle)
# put the object on the response stack
formatted_objects.append(formatted_obj)
return formatted_objects

def dehydrate_links(self, bundle):
"""Dehydrate links field."""

dehydrated = []
obj = bundle.obj
link_fields = [
'extension',
'link_type',
'name',
'mime',
'url'
]
for l in obj.link_set.all():
formatted_link = model_to_dict(l, fields=link_fields)
dehydrated.append(formatted_link)

return dehydrated

def populate_object(self, obj):
"""Populate results with necessary fields
:param obj: Layer obj
:type obj: Layer
:return:
"""
if check_ogc_backend(qgis_server.BACKEND_PACKAGE):
# Provides custom links for QGIS Server styles info
# Default style
try:
obj.qgis_default_style = obj.qgis_layer.default_style
except:
pass

# Styles
try:
obj.qgis_styles = obj.qgis_layer.styles
except:
pass
return obj

def build_bundle(
self, obj=None, data=None, request=None, objects_saved=None):
"""Override build_bundle method to add additional info."""

if obj is None and self._meta.object_class:
obj = self._meta.object_class()

elif obj:
obj = self.populate_object(obj)

return Bundle(
obj=obj,
data=data,
request=request,
objects_saved=objects_saved)

def patch_detail(self, request, **kwargs):
"""Allow patch request to update default_style.
Request body must match this:
{
'default_style': <resource_uri_to_style>
}
"""
reason = 'Can only patch "default_style" field.'
try:
body = json.loads(request.body)
if 'default_style' not in body:
return http.HttpBadRequest(reason=reason)
match = resolve(body['default_style'])
style_id = match.kwargs['id']
api_name = match.kwargs['api_name']
resource_name = match.kwargs['resource_name']
if not (resource_name == 'styles' and api_name == 'api'):
raise Exception()

from geonode.qgis_server.models import QGISServerStyle

style = QGISServerStyle.objects.get(id=style_id)

layer_id = kwargs['id']
layer = Layer.objects.get(id=layer_id)
except:
return http.HttpBadRequest(reason=reason)

from geonode.qgis_server.views import default_qml_style

request.method = 'POST'
response = default_qml_style(
request,
layername=layer.name,
style_name=style.name)

if isinstance(response, TemplateResponse):
if response.status_code == 200:
return HttpResponse(status=200)

return self.error_response(request, response.content)

class Meta(CommonMetaApi):
queryset = Layer.objects.distinct().order_by('-date')
if settings.RESOURCE_PUBLISHING:
queryset = queryset.filter(is_published=True)
resource_name = 'layers'
detail_uri_name = 'id'
include_resource_uri = True
allowed_methods = ['get', 'patch']
excludes = ['csw_anytext', 'metadata_xml']
filtering = CommonMetaApi.filtering
# Allow filtering using ID
filtering.update({
'id': ALL,
'name': ALL,
'typename': ALL,
})


class MapResource(CommonModelApi):
Expand Down
Loading

0 comments on commit a8a8abd

Please sign in to comment.