""" Author: Michel Peltriaux Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany Contact: michel.peltriaux@sgdnord.rlp.de Created on: 16.11.20 """ import json import requests from django.contrib.auth import logout from django.contrib.auth.decorators import login_required from django.http import HttpRequest, HttpResponse, JsonResponse from django.shortcuts import redirect, render, get_object_or_404 from django.template.loader import render_to_string from django.utils import timezone from django.utils.translation import gettext_lazy as _ from compensation.models import Compensation, EcoAccount from intervention.models import Intervention from konova.contexts import BaseContext from konova.decorators import any_group_check from konova.models import Deadline, Geometry, Municipal from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from news.models import ServerMessage from konova.settings import SSO_SERVER_BASE def logout_view(request: HttpRequest): """ Logout route for ending the session manually. Args: request (HttpRequest): The used request object Returns: A redirect """ logout(request) return redirect(SSO_SERVER_BASE) @login_required @any_group_check def home_view(request: HttpRequest): """ Renders the landing page Args: request (HttpRequest): The used request object Returns: A redirect """ template = "konova/home.html" now = timezone.now() user = request.user # Fetch the four newest active and published ServerMessages msgs = ServerMessage.objects.filter( is_active=True, publish_on__lte=now, unpublish_on__gte=now, ).order_by( "-publish_on" )[:3] # First fetch all valid objects (undeleted, only newest versions) interventions = Intervention.objects.filter( deleted=None, ) # Then fetch only user related ones user_interventions = interventions.filter( users__in=[user] ) # Repeat for other objects comps = Compensation.objects.filter( deleted=None, ) user_comps = comps.filter( intervention__users__in=[user] ) eco_accs = EcoAccount.objects.filter( deleted=None, ) user_ecco_accs = eco_accs.filter( users__in=[user] ) additional_context = { "msgs": msgs, "total_intervention_count": interventions.count(), "user_intervention_count": user_interventions.count(), "total_compensation_count": comps.count(), "user_compensation_count": user_comps.count(), "total_eco_count": eco_accs.count(), "user_eco_count": user_ecco_accs.count(), TAB_TITLE_IDENTIFIER: _("Home"), } context = BaseContext(request, additional_context).context return render(request, template, context) def get_geom_parcels(request: HttpRequest, id: str): """ Getter for HTMX Returns all parcels of the requested geometry rendered into a simple HTML table Args: request (HttpRequest): The incoming request id (str): The geometry's id Returns: A rendered piece of HTML """ # HTTP code 286 states that the HTMX should stop polling for updates # https://htmx.org/docs/#polling status_code = 286 template = "konova/includes/parcels/parcel_table_frame.html" geom = get_object_or_404(Geometry, id=id) parcels = geom.get_underlying_parcels() geos_geom = geom.geom parcels_are_currently_calculated = geos_geom is not None and geos_geom.area > 0 and len(parcels) == 0 parcels_available = len(parcels) > 0 no_geometry_given = geos_geom is None if parcels_are_currently_calculated: # Parcels are being calculated right now. Change the status code, so polling stays active for fetching # resutls after the calculation status_code = 200 if parcels_available or no_geometry_given: parcels = parcels.order_by("-municipal", "flr", "flrstck_zhlr", "flrstck_nnr") municipals = parcels.order_by("municipal").distinct("municipal").values("municipal__id") municipals = Municipal.objects.filter(id__in=municipals) rpp = 100 num_all_parcels = parcels.count() parcels = parcels[:rpp] next_page = 1 if len(parcels) < rpp: next_page = None context = { "num_parcels": num_all_parcels, "parcels": parcels, "municipals": municipals, "geom_id": str(id), "next_page": next_page, } html = render_to_string(template, context, request) return HttpResponse(html, status=status_code) else: return HttpResponse(None, status=404) def get_geom_parcels_content(request: HttpRequest, id: str, page: int): """ Getter for infinite scroll of HTMX Returns parcels of a specific page/slice of the found parcel set. Implementation of infinite scroll htmx example: https://htmx.org/examples/infinite-scroll/ Args: request (HttpRequest): The incoming request id (str): The geometry's id page (int): The requested page number Returns: A rendered piece of HTML """ if page < 0: raise AssertionError("Parcel page can not be negative") # HTTP code 286 states that the HTMX should stop polling for updates # https://htmx.org/docs/#polling status_code = 286 template = "konova/includes/parcels/parcel_table_content.html" geom = get_object_or_404(Geometry, id=id) parcels = geom.get_underlying_parcels() parcels = parcels.order_by("-municipal", "flr", "flrstck_zhlr", "flrstck_nnr") rpp = 100 from_p = rpp * (page-1) to_p = rpp * (page) next_page = page + 1 parcels = parcels[from_p:to_p] if len(parcels) < rpp: next_page = None context = { "parcels": parcels, "geom_id": str(id), "next_page": next_page, } html = render_to_string(template, context, request) return HttpResponse(html, status=status_code) def get_404_view(request: HttpRequest, exception=None): """ Returns a 404 handling view Args: request (): exception (): Returns: """ context = BaseContext.context return render(request, "404.html", context, status=404) def get_500_view(request: HttpRequest): """ Returns a 404 handling view Args: request (): Returns: """ context = BaseContext.context return render(request, "500.html", context, status=500) @login_required def map_client_proxy_view(request: HttpRequest): """ 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) body = json.loads(response.content) if response.status_code != 200: return JsonResponse({ "status_code": response.status_code, "content": body, }) return JsonResponse(body)