From 9a4b536843424f84e3dbdde28b596cf670b8b854 Mon Sep 17 00:00:00 2001 From: Moritz Kirmse Date: Mon, 11 Jan 2021 15:37:50 +0100 Subject: [PATCH] fix internal WMS layers (very basic functionality, no precise replication of WMS getCapabilities, but the compleete protocol is not needed in geoportal) --- .../views/getfeatureinfo.py | 9 +- .../geoportailv3_geoportal/views/luxthemes.py | 91 ++++++++++++------- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/geoportal/geoportailv3_geoportal/views/getfeatureinfo.py b/geoportal/geoportailv3_geoportal/views/getfeatureinfo.py index f4526d676..085bd6030 100644 --- a/geoportal/geoportailv3_geoportal/views/getfeatureinfo.py +++ b/geoportal/geoportailv3_geoportal/views/getfeatureinfo.py @@ -5,7 +5,6 @@ import urllib.request import datetime import pyproj -import shapely import geojson import os import json @@ -576,7 +575,7 @@ def get_lux_feature_definition(self, layers): # Check if the layer has a resctriction area restriction = DBSession.query(RestrictionArea).filter( RestrictionArea.roles.any( - Role.id == self.request.user.role.id)).filter( + Role.id == self.request.user.settings_role.id)).filter( RestrictionArea.layers.any( Layer.id == layer ) @@ -591,11 +590,11 @@ def get_lux_feature_definition(self, layers): if self.request.user is not None: if query.filter( LuxGetfeatureDefinition.role == - self.request.user.role.id + self.request.user.settings_role.id ).count() > 0: for res in query.filter( LuxGetfeatureDefinition.role == - self.request.user.role.id).all(): + self.request.user.settings_role.id).all(): luxgetfeaturedefinitions.append(res) else: for res in query.filter( @@ -609,6 +608,7 @@ def get_lux_feature_definition(self, layers): luxgetfeaturedefinitions.append(res) except Exception as e: log.exception(e) + return [] return HTTPBadRequest() return luxgetfeaturedefinitions @@ -1107,6 +1107,7 @@ def _get_external_data(self, layer_id, url, id_column='objectid', result = read_request_with_token(url_request, self.request, log) content = result.data except ESRITokenException as e: + return [] raise HTTPBadGateway(e) except Exception as e: log.exception(e) diff --git a/geoportal/geoportailv3_geoportal/views/luxthemes.py b/geoportal/geoportailv3_geoportal/views/luxthemes.py index b418c9f5e..b3c15c68b 100644 --- a/geoportal/geoportailv3_geoportal/views/luxthemes.py +++ b/geoportal/geoportailv3_geoportal/views/luxthemes.py @@ -1,59 +1,82 @@ -import logging -import re - -from c2cgeoportal_commons.models import DBSession, main -from c2cgeoportal_geoportal.lib.caching import get_region -from c2cgeoportal_geoportal.lib.wmstparsing import TimeInformation -from c2cgeoportal_geoportal.views.theme import Theme from pyramid.view import view_config - +from c2cgeoportal_commons.models import DBSession +from c2cgeoportal_commons.models.main import Theme as ThemeModel +from c2cgeoportal_geoportal.views.theme import Theme +from c2cgeoportal_geoportal.lib.caching import get_region, invalidate_region from geoportailv3_geoportal.models import LuxLayerInternalWMS +import logging log = logging.getLogger(__name__) - -CACHE_REGION = get_region("std") +cache_region = get_region("std") +invalidate_region() +# override c2cgeoportal Entry class to customize handling of WMS and WMTS time positions and prepare +# the theme tree for ngeo time functions class LuxThemes(Theme): + @view_config(route_name="themes", renderer="json") + def themes(self): + return super().themes() + @view_config(route_name='isthemeprivate', renderer='json') def is_theme_private(self): theme = self.request.params.get('theme', '') - cnt = DBSession.query(main.Theme).filter( - main.Theme.public == False).filter( - main.Theme.name == theme).count() # noqa + cnt = DBSession.query(ThemeModel).filter( + ThemeModel.public == False).filter( + ThemeModel.name == theme).count() # noqa if cnt == 1: return {'name': theme, 'is_private': True} return {'name': theme, 'is_private': False} - @view_config(route_name="themes", renderer="json") - def themes(self): - """Fake capabilities for Internal WMS""" - return super().themes() - def _wms_layers(self, ogc_server): - """Fake capabilities for Internal WMS""" if ogc_server.name == "Internal WMS": - return self._wms_layers_internal(), set() + return self._wms_layers_internal() return super()._wms_layers(ogc_server) - @CACHE_REGION.cache_on_arguments() + @cache_region.cache_on_arguments() def _wms_layers_internal(self): - """Fake capabilities for Internal WMS""" - wms_layers = [] - for layer in DBSession.query(LuxLayerInternalWMS): - wms_layers += layer.layers.split(",") if layer.layers else [] - - return { - "layers": { - name: { - "children": [], - "info": [], + layers = {} + for i, layer in enumerate(DBSession.query(LuxLayerInternalWMS)): + for sublayer in layer.layers.split(","): + layers[layer.name + '__' + sublayer] = { + "info": { + "name": layer.name + '__' + sublayer, + }, + "children": [] } - for name in set(wms_layers) - } - } + + return {"layers": layers}, set() + + def _fill_wms(self, layer_theme, layer, errors, mixed): + if isinstance(layer, LuxLayerInternalWMS): + layer_theme["imageType"] = layer.ogc_server.image_type + if layer.style: # pragma: no cover + layer_theme["style"] = layer.style + + wms, wms_errors = self._wms_layers(layer.ogc_server) + errors |= wms_errors + if wms is None: + return + layer_theme["childLayers"] = [] + for layer_name in layer.layers.split(","): + full_layer_name = layer.name + '__' + layer_name + if full_layer_name in wms["layers"]: + wms_layer_obj = wms["layers"][full_layer_name] + if not wms_layer_obj["children"]: + layer_theme["childLayers"].append(wms["layers"][full_layer_name]["info"]) + else: + for child_layer in wms_layer_obj["children"]: + layer_theme["childLayers"].append(wms["layers"][child_layer]["info"]) + else: + errors.add( + "The sublayer '{}' of internal layer {} is not defined in WMS capabilities".format( + layer_name, layer.name + ) + ) + else: + return super()._fill_wms(layer_theme, layer, errors, mixed)