<commit_before>import json
import logging
from collections import defaultdict

from django.contrib.gis.db.models.functions import Transform
from django.contrib.auth.decorators import permission_required
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from django.shortcuts import redirect
from django.views.decorators.http import last_modified as cache_last_modified
from django.views.decorators.cache import cache_control
from django.views.generic import TemplateView
from django.utils.translation import ugettext as _
from django.core.cache import caches
from django.views.generic.detail import BaseDetailView
from django.http import HttpResponseRedirect
from rest_framework import permissions as rest_permissions

from mapentity.serializers import GPXSerializer
from mapentity.views import (MapEntityLayer, MapEntityList, MapEntityJsonList, MapEntityViewSet,
                             MapEntityDetail, MapEntityDocument, MapEntityCreate, MapEntityUpdate,
                             MapEntityDelete, MapEntityFormat, HttpJSONResponse, LastModifiedMixin,)


from geotrek.authent.decorators import same_structure_required
from geotrek.common.utils import classproperty
from geotrek.common.views import PublicOrReadPermMixin
from geotrek.core.models import AltimetryMixin

from .models import Path, Trail, Topology
from .forms import PathForm, TrailForm
from .filters import PathFilterSet, TrailFilterSet
from .serializers import PathSerializer, PathGeojsonSerializer, TrailSerializer, TrailGeojsonSerializer
from . import graph as graph_lib
from django.http.response import HttpResponse, JsonResponse
from django.contrib import messages
from django.db.models import Sum
from geotrek.api.v2.functions import Length
from django.db.models.fields import FloatField


logger = logging.getLogger(__name__)


class CreateFromTopologyMixin(object):
    def on_topology(self):
        pk = self.request.GET.get('topology')
        if pk:
            try:
                return Topology.objects.existing().get(pk=pk)
            except Topology.DoesNotExist:
                logger.warning("Intervention on unknown topology %s" % pk)
        return None

    def get_initial(self):
        initial = super(CreateFromTopologyMixin, self).get_initial()
        # Create intervention with an existing topology as initial data
        topology = self.on_topology()
        if topology:
            initial['topology'] = topology.serialize(with_pk=False)
        return initial


class PathLayer(MapEntityLayer):
    properties = ['name', 'draft']
    queryset = Path.objects.all()

    def get_queryset(self):
        qs = super(PathLayer, self).get_queryset()
        if self.request.GET.get('no_draft'):
            qs = qs.exclude(draft=True)
        return qs

    def view_cache_key(self):
        """Used by the ``view_cache_response_content`` decorator.
        """
        language = self.request.LANGUAGE_CODE
        latest_saved = Path.latest_updated()
        geojson_lookup = None
        if latest_saved:
            geojson_lookup = '%s_path_%s%s_json_layer' % (
                language,
                latest_saved.strftime('%y%m%d%H%M%S%f'),
                '_nodraft' if self.request.GET.get('no_draft') == 'true' else ''
            )
        return geojson_lookup


class PathList(MapEntityList):
    queryset = Path.objects.all()
    filterform = PathFilterSet

    @classproperty
    def columns(cls):
        columns = ['id', 'checkbox', 'name', 'length', 'length_2d']
        return columns


class PathJsonList(MapEntityJsonList, PathList):
    def get_context_data(self, **kwargs):
        context = super(PathJsonList, self).get_context_data(**kwargs)
        context["sumPath"] = round((self.object_list.aggregate(
            sumPath=Sum(Length('geom'), output_field=FloatField())
        ).get('sumPath') or 0) / 1000, 1)
        return context


class PathFormatList(MapEntityFormat, PathList):
    columns = [
        'id', 'structure', 'valid', 'visible', 'name', 'comments', 'departure', 'arrival',
        'comfort', 'source', 'stake', 'usages', 'networks',
        'date_insert', 'date_update',
        'cities', 'districts', 'areas', 'length_2d'
    ] + AltimetryMixin.COLUMNS


class PathDetail(MapEntityDetail):
    model = Path

    def get_context_data(self, *args, **kwargs):
        context = super(PathDetail, self).get_context_data(*args, **kwargs)
        context['can_edit'] = self.get_object().same_structure(self.request.user)
        return context


class PathGPXDetail(LastModifiedMixin, PublicOrReadPermMixin, BaseDetailView):
    queryset = Path.objects.all()

    def render_to_response(self, context):
        gpx_serializer = GPXSerializer()
        response = HttpResponse(content_type='application/gpx+xml')
        response['Content-Disposition'] = 'attachment; filename="%s.gpx"' % self.object
        gpx_serializer.serialize([self.object], stream=response, gpx_field='geom_3d')
        return response


class PathKMLDetail(LastModifiedMixin, PublicOrReadPermMixin, BaseDetailView):
    queryset = Path.objects.all()

    def render_to_response(self, context):
        response = HttpResponse(self.object.kml(),
                                content_type='application/vnd.google-earth.kml+xml')
        response['Content-Disposition'] = 'attachment; filename="%s.kml"' % self.object
        return response


class PathDocument(MapEntityDocument):
    model = Path

    def get_context_data(self, *args, **kwargs):
        language = self.request.LANGUAGE_CODE
        self.get_object().prepare_elevation_chart(language, self.request.build_absolute_uri('/'))
        return super(PathDocument, self).get_context_data(*args, **kwargs)


class PathCreate(MapEntityCreate):
    model = Path
    form_class = PathForm

    def dispatch(self, *args, **kwargs):
        if self.request.user.has_perm('core.add_path') or self.request.user.has_perm('core.add_draft_path'):
            return super(MapEntityCreate, self).dispatch(*args, **kwargs)
        return super(PathCreate, self).dispatch(*args, **kwargs)


class PathUpdate(MapEntityUpdate):
    model = Path
    form_class = PathForm

    @same_structure_required('core:path_detail')
    def dispatch(self, *args, **kwargs):
        path = self.get_object()
        if path.draft and not self.request.user.has_perm('core.change_draft_path'):
            messages.warning(self.request, _(
                'Access to the requested resource is restricted. You have been redirected.'))
            return redirect('core:path_detail', **kwargs)
        if not path.draft and not self.request.user.has_perm('core.change_path'):
            messages.warning(self.request, _(
                'Access to the requested resource is restricted. You have been redirected.'))
            return redirect('core:path_detail', **kwargs)
        if path.draft and self.request.user.has_perm('core.change_draft_path'):
            return super(MapEntityUpdate, self).dispatch(*args, **kwargs)
        return super(PathUpdate, self).dispatch(*args, **kwargs)


class MultiplePathDelete(TemplateView):
    template_name = "core/multiplepath_confirm_delete.html"
    model = Path
    success_url = "core:path_list"

    def dispatch(self, *args, **kwargs):
        self.paths_pk = self.kwargs['pk'].split(',')
        self.paths = []
        for pk in self.paths_pk:
            path = Path.objects.get(pk=pk)
            self.paths.append(path)
            if path.draft and not self.request.user.has_perm('core.delete_draft_path'):
                messages.warning(self.request, _(
                    'Access to the requested resource is restricted. You have been redirected.'))
                return redirect('core:path_list')
            if not path.draft and not self.request.user.has_perm('core.delete_path'):
                messages.warning(self.request, _(
                    'Access to the requested resource is restricted. You have been redirected.'))
                return redirect('core:path_list')
            if not path.same_structure(self.request.user):
                messages.warning(self.request, _('Access to the requested resource is restricted by structure. '
                                                 'You have been redirected.'))
                return redirect('core:path_list')<commit_msg>Fix get form kwargs delete draft path permission<commit_after>import json
import logging
from collections import defaultdict

from django.contrib.gis.db.models.functions import Transform
from django.contrib.auth.decorators import permission_required
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from django.shortcuts import redirect
from django.views.decorators.http import last_modified as cache_last_modified
from django.views.decorators.cache import cache_control
from django.views.generic import TemplateView
from django.utils.translation import ugettext as _
from django.core.cache import caches
from django.views.generic.detail import BaseDetailView
from django.http import HttpResponseRedirect
from rest_framework import permissions as rest_permissions

from mapentity.serializers import GPXSerializer
from mapentity.views import (MapEntityLayer, MapEntityList, MapEntityJsonList, MapEntityViewSet,
                             MapEntityDetail, MapEntityDocument, MapEntityCreate, MapEntityUpdate,
                             MapEntityDelete, MapEntityFormat, HttpJSONResponse, LastModifiedMixin,)


from geotrek.authent.decorators import same_structure_required
from geotrek.common.utils import classproperty
from geotrek.common.views import PublicOrReadPermMixin
from geotrek.core.models import AltimetryMixin

from .models import Path, Trail, Topology
from .forms import PathForm, TrailForm
from .filters import PathFilterSet, TrailFilterSet
from .serializers import PathSerializer, PathGeojsonSerializer, TrailSerializer, TrailGeojsonSerializer
from . import graph as graph_lib
from django.http.response import HttpResponse, JsonResponse
from django.contrib import messages
from django.db.models import Sum
from geotrek.api.v2.functions import Length
from django.db.models.fields import FloatField


logger = logging.getLogger(__name__)


class CreateFromTopologyMixin(object):
    def on_topology(self):
        pk = self.request.GET.get('topology')
        if pk:
            try:
                return Topology.objects.existing().get(pk=pk)
            except Topology.DoesNotExist:
                logger.warning("Intervention on unknown topology %s" % pk)
        return None

    def get_initial(self):
        initial = super(CreateFromTopologyMixin, self).get_initial()
        # Create intervention with an existing topology as initial data
        topology = self.on_topology()
        if topology:
            initial['topology'] = topology.serialize(with_pk=False)
        return initial


class PathLayer(MapEntityLayer):
    properties = ['name', 'draft']
    queryset = Path.objects.all()

    def get_queryset(self):
        qs = super(PathLayer, self).get_queryset()
        if self.request.GET.get('no_draft'):
            qs = qs.exclude(draft=True)
        return qs

    def view_cache_key(self):
        """Used by the ``view_cache_response_content`` decorator.
        """
        language = self.request.LANGUAGE_CODE
        latest_saved = Path.latest_updated()
        geojson_lookup = None
        if latest_saved:
            geojson_lookup = '%s_path_%s%s_json_layer' % (
                language,
                latest_saved.strftime('%y%m%d%H%M%S%f'),
                '_nodraft' if self.request.GET.get('no_draft') == 'true' else ''
            )
        return geojson_lookup


class PathList(MapEntityList):
    queryset = Path.objects.all()
    filterform = PathFilterSet

    @classproperty
    def columns(cls):
        columns = ['id', 'checkbox', 'name', 'length', 'length_2d']
        return columns


class PathJsonList(MapEntityJsonList, PathList):
    def get_context_data(self, **kwargs):
        context = super(PathJsonList, self).get_context_data(**kwargs)
        context["sumPath"] = round((self.object_list.aggregate(
            sumPath=Sum(Length('geom'), output_field=FloatField())
        ).get('sumPath') or 0) / 1000, 1)
        return context


class PathFormatList(MapEntityFormat, PathList):
    columns = [
        'id', 'structure', 'valid', 'visible', 'name', 'comments', 'departure', 'arrival',
        'comfort', 'source', 'stake', 'usages', 'networks',
        'date_insert', 'date_update',
        'cities', 'districts', 'areas', 'length_2d'
    ] + AltimetryMixin.COLUMNS


class PathDetail(MapEntityDetail):
    model = Path

    def get_context_data(self, *args, **kwargs):
        context = super(PathDetail, self).get_context_data(*args, **kwargs)
        context['can_edit'] = self.get_object().same_structure(self.request.user)
        return context


class PathGPXDetail(LastModifiedMixin, PublicOrReadPermMixin, BaseDetailView):
    queryset = Path.objects.all()

    def render_to_response(self, context):
        gpx_serializer = GPXSerializer()
        response = HttpResponse(content_type='application/gpx+xml')
        response['Content-Disposition'] = 'attachment; filename="%s.gpx"' % self.object
        gpx_serializer.serialize([self.object], stream=response, gpx_field='geom_3d')
        return response


class PathKMLDetail(LastModifiedMixin, PublicOrReadPermMixin, BaseDetailView):
    queryset = Path.objects.all()

    def render_to_response(self, context):
        response = HttpResponse(self.object.kml(),
                                content_type='application/vnd.google-earth.kml+xml')
        response['Content-Disposition'] = 'attachment; filename="%s.kml"' % self.object
        return response


class PathDocument(MapEntityDocument):
    model = Path

    def get_context_data(self, *args, **kwargs):
        language = self.request.LANGUAGE_CODE
        self.get_object().prepare_elevation_chart(language, self.request.build_absolute_uri('/'))
        return super(PathDocument, self).get_context_data(*args, **kwargs)


class PathCreate(MapEntityCreate):
    model = Path
    form_class = PathForm

    def dispatch(self, *args, **kwargs):
        if self.request.user.has_perm('core.add_path') or self.request.user.has_perm('core.add_draft_path'):
            return super(MapEntityCreate, self).dispatch(*args, **kwargs)
        return super(PathCreate, self).dispatch(*args, **kwargs)


class PathUpdate(MapEntityUpdate):
    model = Path
    form_class = PathForm

    @same_structure_required('core:path_detail')
    def dispatch(self, *args, **kwargs):
        path = self.get_object()
        if path.draft and not self.request.user.has_perm('core.change_draft_path'):
            messages.warning(self.request, _(
                'Access to the requested resource is restricted. You have been redirected.'))
            return redirect('core:path_detail', **kwargs)
        if not path.draft and not self.request.user.has_perm('core.change_path'):
            messages.warning(self.request, _(
                'Access to the requested resource is restricted. You have been redirected.'))
            return redirect('core:path_detail', **kwargs)
        if path.draft and self.request.user.has_perm('core.change_draft_path'):
            return super(MapEntityUpdate, self).dispatch(*args, **kwargs)
        return super(PathUpdate, self).dispatch(*args, **kwargs)

    def get_form_kwargs(self):
        kwargs = super(PathUpdate, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        path = self.get_object()
        if path.draft and self.request.user.has_perm('core.delete_draft_path'):
            kwargs['can_delete'] = True
        return kwargs


class MultiplePathDelete(TemplateView):
    template_name = "core/multiplepath_confirm_delete.html"
    model = Path
    success_url = "core:path_list"

    def dispatch(self, *args, **kwargs):
        self.paths_pk = self.kwargs['pk'].split(',')
        self.paths = []
        for pk in self.paths_pk:
            path = Path.objects.get(pk=pk)
            self.paths.append(path)
            if path.draft and not self.request.user.has_perm('core.delete_draft_path'):
                messages.warning(self.request, _(
                    'Access to the requested resource is restricted. You have been redirected.'))
                return redirect('core:path_list')
            if not path.draft and not self.request.user.has_perm('core.delete_path'):
                messages.warning(self.request, _(
                    'Access to the requested resource is restricted. You have been redirected.'))
                return redirect('core:path_list')
            if not path.same_structure(self.request.user):
                messages.warning(self.request, _('Access to the requested resource is restricted by structure. '
                                                 'You have been redirected.'))
                return redirect('core:path_list')
{'fraction_non_alphanumeric': 0.1012613875262789, 'fraction_numerical': 0.00116795141322121, 'mean_word_length': 3.2024539877300615, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '473285', 'n_tokens_mistral': 4778, 'n_tokens_neox': 4638, 'n_words': 1109}