Merge branch 'map_client_parcel_wfs_proxy' into netgis_client_update
This commit is contained in:
		
						commit
						c5d073b06b
					
				@ -130,7 +130,7 @@
 | 
			
		||||
                            {% else %}
 | 
			
		||||
                            <span title="{% trans 'The data must be shared with you, if you want to see which other users have shared access as well.' %}">
 | 
			
		||||
                                {% fa5_icon 'eye-slash' %}
 | 
			
		||||
                                {{obj.users.count}} {% trans 'other users' %}
 | 
			
		||||
                                {{obj.intervention.users.count}} {% trans 'other users' %}
 | 
			
		||||
                            </span>
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
                        </td>
 | 
			
		||||
 | 
			
		||||
@ -152,7 +152,7 @@ class EgonGmlBuilder:
 | 
			
		||||
                    "oneo:aufnahmezeitpunkt": doc.date_of_creation.strftime(DEFAULT_DATE_FORMAT),
 | 
			
		||||
                    "oneo:bemerkung": doc.comment,
 | 
			
		||||
                    "oneo:fotoverweis": base64.b64encode(doc.file.read()).decode("utf-8"),
 | 
			
		||||
                    "oneo:dateiname": doc.title,
 | 
			
		||||
                    "oneo:dateiname": doc.file.url.split("/")[-1],
 | 
			
		||||
                    "oneo:hauptfoto": False,
 | 
			
		||||
                }
 | 
			
		||||
            } for doc in regular_docs
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										69
									
								
								konova/management/commands/quality_check.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								konova/management/commands/quality_check.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
			
		||||
"""
 | 
			
		||||
Author: Michel Peltriaux
 | 
			
		||||
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
 | 
			
		||||
Contact: ksp-servicestelle@sgdnord.rlp.de
 | 
			
		||||
Created on: 01.02.23
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
from compensation.models import Compensation, EcoAccount
 | 
			
		||||
from compensation.utils.quality import CompensationQualityChecker, EcoAccountQualityChecker
 | 
			
		||||
from ema.models import Ema
 | 
			
		||||
from ema.utils.quality import EmaQualityChecker
 | 
			
		||||
from intervention.models import Intervention
 | 
			
		||||
from intervention.utils.quality import InterventionQualityChecker
 | 
			
		||||
from konova.management.commands.setup import BaseKonovaCommand
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Command(BaseKonovaCommand):
 | 
			
		||||
    help = "Runs quality check on certain entries"
 | 
			
		||||
 | 
			
		||||
    __interventions = []
 | 
			
		||||
    __compensations = []
 | 
			
		||||
    __ecoaccount = []
 | 
			
		||||
    __ema = []
 | 
			
		||||
    identifier_like = None
 | 
			
		||||
    title_like = None
 | 
			
		||||
 | 
			
		||||
    def add_arguments(self, parser):
 | 
			
		||||
        try:
 | 
			
		||||
            parser.add_argument("--identifier-like", type=str)
 | 
			
		||||
            parser.add_argument("--title-like", type=str)
 | 
			
		||||
        except ValueError as e:
 | 
			
		||||
            self._write_error(f"Argument error: {e}")
 | 
			
		||||
            exit(-1)
 | 
			
		||||
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
        self.__handle_arguments(options)
 | 
			
		||||
        self.__get_objects()
 | 
			
		||||
        self.perform_quality_check()
 | 
			
		||||
 | 
			
		||||
    def __handle_arguments(self, options):
 | 
			
		||||
        self.identifier_like = options["identifier_like"] or ""
 | 
			
		||||
        self.title_like = options["title_like"] or ""
 | 
			
		||||
 | 
			
		||||
    def __get_objects(self):
 | 
			
		||||
        _filter = {
 | 
			
		||||
            "identifier__icontains": self.identifier_like,
 | 
			
		||||
            "title__icontains": self.title_like,
 | 
			
		||||
        }
 | 
			
		||||
        self.__interventions = Intervention.objects.filter(**_filter)
 | 
			
		||||
        self.__compensations = Compensation.objects.filter(**_filter)
 | 
			
		||||
        self.__ecoaccount = EcoAccount.objects.filter(**_filter)
 | 
			
		||||
        self.__ema = Ema.objects.filter(**_filter)
 | 
			
		||||
 | 
			
		||||
    def perform_quality_check(self):
 | 
			
		||||
        # Interventions
 | 
			
		||||
        _runs = [
 | 
			
		||||
            (self.__interventions, InterventionQualityChecker),
 | 
			
		||||
            (self.__compensations, CompensationQualityChecker),
 | 
			
		||||
            (self.__ecoaccount, EcoAccountQualityChecker),
 | 
			
		||||
            (self.__ema, EmaQualityChecker),
 | 
			
		||||
        ]
 | 
			
		||||
        for run in _runs:
 | 
			
		||||
            entries = run[0]
 | 
			
		||||
            CheckerClass = run[1]
 | 
			
		||||
            for entry in entries:
 | 
			
		||||
                checker = CheckerClass(entry)
 | 
			
		||||
                checker.run_check()
 | 
			
		||||
                if not checker.valid:
 | 
			
		||||
                    self._write_error(f"{entry.identifier};{';'.join(str(msg) for msg in checker.messages)}")
 | 
			
		||||
@ -10,4 +10,7 @@ proxy = ""
 | 
			
		||||
PROXIES = {
 | 
			
		||||
    "http": proxy,
 | 
			
		||||
    "https": proxy,
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CLIENT_PROXY_AUTH_USER = "CHANGE_ME"
 | 
			
		||||
CLIENT_PROXY_AUTH_PASSWORD = "CHANGE_ME"
 | 
			
		||||
@ -22,7 +22,7 @@ from konova.sso.sso import KonovaSSOClient
 | 
			
		||||
from konova.views.logout import logout_view
 | 
			
		||||
from konova.views.geometry import get_geom_parcels, get_geom_parcels_content
 | 
			
		||||
from konova.views.home import home_view
 | 
			
		||||
from konova.views.map_proxy import map_client_proxy_view
 | 
			
		||||
from konova.views.map_proxy import ClientProxyParcelSearch, ClientProxyParcelWFS
 | 
			
		||||
 | 
			
		||||
sso_client = KonovaSSOClient(SSO_SERVER, SSO_PUBLIC_KEY, SSO_PRIVATE_KEY)
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
@ -40,7 +40,8 @@ urlpatterns = [
 | 
			
		||||
    path('api/', include("api.urls")),
 | 
			
		||||
    path('geom/<id>/parcels/', get_geom_parcels, name="geometry-parcels"),
 | 
			
		||||
    path('geom/<id>/parcels/<int:page>', get_geom_parcels_content, name="geometry-parcels-content"),
 | 
			
		||||
    path('client/proxy', map_client_proxy_view, name="map-client-proxy"),
 | 
			
		||||
    path('client/proxy', ClientProxyParcelSearch.as_view(), name="client-proxy-search"),
 | 
			
		||||
    path('client/proxy/wfs', ClientProxyParcelWFS.as_view(), name="client-proxy-wfs"),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
if DEBUG:
 | 
			
		||||
 | 
			
		||||
@ -10,31 +10,86 @@ import json
 | 
			
		||||
import requests
 | 
			
		||||
from django.contrib.auth.decorators import login_required
 | 
			
		||||
from django.http import JsonResponse, HttpRequest
 | 
			
		||||
from django.utils.decorators import method_decorator
 | 
			
		||||
from django.utils.http import urlencode
 | 
			
		||||
from django.views import View
 | 
			
		||||
from requests.auth import HTTPDigestAuth
 | 
			
		||||
 | 
			
		||||
from konova.sub_settings.proxy_settings import PROXIES
 | 
			
		||||
from konova.sub_settings.proxy_settings import PROXIES, CLIENT_PROXY_AUTH_USER, CLIENT_PROXY_AUTH_PASSWORD
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@login_required
 | 
			
		||||
def map_client_proxy_view(request: HttpRequest):
 | 
			
		||||
class BaseClientProxyView(View):
 | 
			
		||||
    """ Provides proxy functionality for NETGIS map client.
 | 
			
		||||
 | 
			
		||||
    Used for fetching content of a provided url
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        request (HttpRequest): The incoming request
 | 
			
		||||
 | 
			
		||||
    Returns:
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    url = request.META.get("QUERY_STRING")
 | 
			
		||||
    response = requests.get(url, proxies=PROXIES)
 | 
			
		||||
    content = response.content
 | 
			
		||||
    if isinstance(content, bytes):
 | 
			
		||||
        content = content.decode("utf-8")
 | 
			
		||||
    body = json.loads(content)
 | 
			
		||||
    if response.status_code != 200:
 | 
			
		||||
        return JsonResponse({
 | 
			
		||||
            "status_code": response.status_code,
 | 
			
		||||
            "content": body,
 | 
			
		||||
        })
 | 
			
		||||
    return JsonResponse(body)
 | 
			
		||||
    class Meta:
 | 
			
		||||
        abstract = True
 | 
			
		||||
 | 
			
		||||
    @method_decorator(login_required)
 | 
			
		||||
    def dispatch(self, request, *args, **kwargs):
 | 
			
		||||
        return super().dispatch(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def perform_url_call(self, url, headers={}, auth=None):
 | 
			
		||||
        """ Generic proxied call
 | 
			
		||||
 | 
			
		||||
        Args:
 | 
			
		||||
            url (str): The url to call
 | 
			
		||||
            headers (dict): Optional headers
 | 
			
		||||
            auth: Optional authentication info
 | 
			
		||||
 | 
			
		||||
        Returns:
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        response = requests.get(
 | 
			
		||||
            url,
 | 
			
		||||
            proxies=PROXIES,
 | 
			
		||||
            headers=headers,
 | 
			
		||||
            auth=auth
 | 
			
		||||
        )
 | 
			
		||||
        content = response.content
 | 
			
		||||
        if isinstance(content, bytes):
 | 
			
		||||
            content = content.decode("utf-8")
 | 
			
		||||
        return content, response.status_code
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ClientProxyParcelSearch(BaseClientProxyView):
 | 
			
		||||
 | 
			
		||||
    def get(self, request: HttpRequest):
 | 
			
		||||
        url = request.META.get("QUERY_STRING")
 | 
			
		||||
        content, response_code = self.perform_url_call(url)
 | 
			
		||||
        body = json.loads(content)
 | 
			
		||||
        if response_code != 200:
 | 
			
		||||
            return JsonResponse({
 | 
			
		||||
                "status_code": response_code,
 | 
			
		||||
                "content": body,
 | 
			
		||||
            })
 | 
			
		||||
        return JsonResponse(body)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ClientProxyParcelWFS(BaseClientProxyView):
 | 
			
		||||
 | 
			
		||||
    def get(self, request: HttpRequest):
 | 
			
		||||
        params = request.GET.dict()
 | 
			
		||||
        params["version"] = "2.0.0"
 | 
			
		||||
        params["outputformat"] = "application/json; subtype=geojson"
 | 
			
		||||
        base_url = "https://www.geoportal.rlp.de/registry/wfs/519"
 | 
			
		||||
        url = f"{base_url}?{urlencode(params, doseq=True)}"
 | 
			
		||||
 | 
			
		||||
        url = url.replace("typename", "typenames")
 | 
			
		||||
        auth = HTTPDigestAuth(CLIENT_PROXY_AUTH_USER, CLIENT_PROXY_AUTH_PASSWORD)
 | 
			
		||||
 | 
			
		||||
        content, response_code = self.perform_url_call(url, auth=auth)
 | 
			
		||||
        body = json.loads(content)
 | 
			
		||||
        body["crs"] = {
 | 
			
		||||
            "type": "name",
 | 
			
		||||
            "properties": {
 | 
			
		||||
                "name": "urn:ogc:def:crs:EPSG::25832"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if response_code != 200:
 | 
			
		||||
            return JsonResponse({
 | 
			
		||||
                "status_code": response_code,
 | 
			
		||||
                "content": body,
 | 
			
		||||
            })
 | 
			
		||||
        resp = JsonResponse(body)
 | 
			
		||||
        return resp
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@
 | 
			
		||||
 | 
			
		||||
		{ "folder": 1, "type": "WMS", "title": "Lagebezeichnungen", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "Lagebezeichnungen" },
 | 
			
		||||
		{ "folder": 1, "type": "WMS", "title": "Flurstücke", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "Flurstueck", "active":  true},
 | 
			
		||||
		{ "folder": 1, "type": "WFS", "title": "Flurstücke (WFS)", "url": "/client/proxy/wfs?", "name": "ave:Flurstueck"},
 | 
			
		||||
		{ "folder": 1, "type": "WMS", "title": "Gebäude / Bauwerke", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "GebaeudeBauwerke" },
 | 
			
		||||
		{ "folder": 1, "type": "WMS", "title": "Nutzung", "url": "https://geo5.service24.rlp.de/wms/liegenschaften_rp.fcgi?", "name": "Nutzung" },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user