예제 #1
0
    def post(self, request, slug, feature_type_slug):

        context = {}
        try:
            up_file = request.FILES['image_file']
        except Exception:
            logger.exception('ImportFromImage.post')
            context['status'] = "error"
            context['message'] = "Erreur à l'import du fichier. "
            status = 400

        try:
            data_geom_wkt = exif.get_image_geoloc_as_wkt(up_file,
                                                         with_alt=False,
                                                         ewkt=False)
        except Exception:
            logger.exception('ImportFromImage.post')
            context['status'] = "error"
            context['message'] = "Erreur lors de la lecture des données GPS. "
            status = 400
        else:
            geom = self.get_geom(data_geom_wkt)
            context['geom'] = geom.wkt
            context['status'] = "success"
            status = 200

        return JsonResponse(context, status=status)
예제 #2
0
    def get(self, request, slug, action):
        project = self.get_object()
        user = request.user

        if action.lower() not in ['ajouter', 'annuler']:
            msg = "Erreur de syntaxe dans l'url d'abonnement. "
            logger.error(msg)
            messages.error(request, "Cette action est incorrecte")

        elif action.lower() == 'ajouter':
            obj, _created = Subscription.objects.get_or_create(
                project=project, )
            obj.users.add(user)
            obj.save()
            messages.info(
                request,
                'Vous êtes maintenant abonné aux notifications de ce projet. ')

        elif action.lower() == 'annuler':
            try:
                obj = Subscription.objects.get(project=project)
                obj.users.remove(user)
                obj.save()
                messages.info(
                    request,
                    'Vous ne recevrez plus les notifications de ce projet. ')
            except Exception:
                logger.exception('SubscribingView.get')

        return redirect('geocontrib:project', slug=slug)
예제 #3
0
def set_auth_member(sender, instance, created, **kwargs):
    Authorization = apps.get_model(app_label='geocontrib',
                                   model_name="Authorization")
    UserLevelPermission = apps.get_model(app_label='geocontrib',
                                         model_name="UserLevelPermission")
    Project = apps.get_model(app_label='geocontrib', model_name="Project")
    if created:
        try:
            for project in Project.objects.all():
                Authorization.objects.create(
                    project=project,
                    user=instance,
                    level=UserLevelPermission.objects.get(rank=1))
        except Exception:
            logger.exception('Trigger.set_auth_member')
    elif not instance.is_active:
        try:
            for project in Project.objects.all():
                Authorization.objects.update_or_create(
                    project=project,
                    user=instance,
                    defaults={
                        'level': UserLevelPermission.objects.get(rank=0)
                    })
        except Exception:
            logger.exception('Trigger.set_auth_member')
예제 #4
0
def set_users_perms(sender, instance, created, **kwargs):
    # On ajoute la permission d'admin de projet au créateur
    if created:
        Authorization = apps.get_model(app_label='geocontrib',
                                       model_name="Authorization")
        UserLevelPermission = apps.get_model(app_label='geocontrib',
                                             model_name="UserLevelPermission")
        User = apps.get_model(app_label='geocontrib', model_name="User")
        try:
            Authorization.objects.create(
                project=instance,
                user=instance.creator,
                level=UserLevelPermission.objects.get(rank=4))
        except Exception:
            logger.exception('Trigger.set_users_perms')
        try:
            for user in User.objects.filter(is_active=True).exclude(
                    pk=instance.creator.pk):
                Authorization.objects.update_or_create(
                    project=instance,
                    user=user,
                    defaults={
                        'level': UserLevelPermission.objects.get(rank=1)
                    })
        except Exception:
            logger.exception('Trigger.set_users_perms')
예제 #5
0
def notify_or_stack_events(sender, instance, created, **kwargs):

    if created and instance.project_slug and settings.DEFAULT_SENDING_FREQUENCY != 'never':
        # On empile les evenements pour notifier les abonnés, en fonction de la fréquence d'envoi
        StackedEvent = apps.get_model(app_label='geocontrib', model_name="StackedEvent")
        stack, _ = StackedEvent.objects.get_or_create(
            sending_frequency=settings.DEFAULT_SENDING_FREQUENCY, state='pending',
            project_slug=instance.project_slug)
        stack.events.add(instance)
        stack.save()

        # On notifie les collaborateurs des messages nécessitant une action immédiate
        try:
            instance.ping_users()
        except Exception:
            logger.exception('ping_users@notify_or_stack_events')
예제 #6
0
 def __init__(self, *args, **kwargs):
     feature_type = kwargs.pop('feature_type', None)
     feature = kwargs.pop('feature', None)
     super().__init__(*args, **kwargs)
     qs = Feature.objects.all()
     if feature_type:
         qs = qs.filter(feature_type=feature_type)
     if feature:
         qs = qs.exclude(feature_id=feature.feature_id)
     try:
         self.fields['feature_to'].queryset = qs
         self.fields[
             'feature_to'].label_from_instance = lambda obj: "{} ({} - {})".format(
                 obj.title, obj.display_creator,
                 obj.created_on.strftime("%d/%m/%Y %H:%M"))
     except Exception:
         logger.exception('No related features found')
예제 #7
0
    def get_context_data(self, feature_id=None, **kwargs):
        self.object = self.get_object()
        context = super().get_context_data(**kwargs)
        try:
            request = self.request
            project = None
            title = None
            if any([isinstance(self.object, model) for model in [Project, FeatureType, Feature]]):
                title = self.object.title
            if isinstance(self.object, Project):
                project = self.object
            elif isinstance(self.object, FeatureType) or isinstance(self.object, Feature):
                project = self.object.project

            serialized_base_maps = BaseMapSerializer(
                BaseMap.objects.filter(project=project),
                many=True
            )
            serialized_layers = LayerSerializer(
                Layer.objects.all(),
                many=True
            )
            features = Feature.handy.availables(user=self.request.user, project=project)

            if feature_id:
                features = features.filter(feature_id=feature_id)

            serialized_features = FeatureDetailedSerializer(
                features,
                is_authenticated=request.user.is_authenticated,
                context={'request': request},
                many=True
            )
            context['serialized_features'] = serialized_features.data
            context['serialized_base_maps'] = serialized_base_maps.data
            context['serialized_layers'] = serialized_layers.data
            context['title'] = title
        except Exception:
            logger.exception('BaseMapContext error')
        return context
예제 #8
0
    def post(self, request, slug, feature_type_slug):
        feature_type = self.get_object()
        try:
            up_file = request.FILES['json_file'].read()
            data = json.loads(up_file.decode('utf-8'))
        except Exception:
            logger.exception('ImportFromGeoJSON.post')
            messages.error(request, "Erreur à l'import du fichier. ")
        else:
            try:
                with transaction.atomic():
                    self.check_feature_type_slug(request, data,
                                                 feature_type_slug)
                    self.create_features(request, request.user, data,
                                         feature_type)
            except IntegrityError:
                messages.error(
                    request, "Erreur lors de l'import d'un fichier GeoJSON. ")

        return redirect('geocontrib:feature_type_detail',
                        slug=slug,
                        feature_type_slug=feature_type_slug)
예제 #9
0
    def post(self, request, slug, feature_type_slug):

        user = request.user
        feature_type = self.get_object()
        project = feature_type.project
        permissions = Authorization.all_permissions(user, project)

        feature_form = FeatureBaseForm(request.POST,
                                       feature_type=feature_type,
                                       user=user)
        extra = CustomField.objects.filter(feature_type=feature_type)
        extra_form = FeatureExtraForm(request.POST, extra=extra)

        linked_formset = self.LinkedFormset(
            request.POST or None,
            prefix='linked',
            form_kwargs={'feature_type': feature_type},
        )

        attachment_formset = self.AttachmentFormset(request.POST or None,
                                                    request.FILES,
                                                    prefix='attachment')

        all_forms = [
            feature_form,
            extra_form,
            attachment_formset,
            linked_formset,
        ]

        forms_are_valid = all([ff.is_valid() for ff in all_forms])

        if forms_are_valid:
            try:
                feature = feature_form.save(project=project,
                                            feature_type=feature_type,
                                            creator=user,
                                            extra=extra_form.cleaned_data)
            except Exception as err:
                logger.exception('FeatureCreate.post')
                messages.error(
                    request,
                    "Une erreur s'est produite lors de la création du signalement {title}: {err}"
                    .format(title=feature_form.cleaned_data.get(
                        'title', 'N/A'),
                            err=str(err)))
            else:

                # Traitement des signalements liés
                for data in linked_formset.cleaned_data:
                    feature_link = data.pop('id', None)

                    if feature_link:
                        if not data.get('DELETE'):
                            feature_link.relation_type = data.get(
                                'relation_type')
                            feature_link.feature_to = data.get('feature_to')
                            feature_link.save()

                        if data.get('DELETE'):
                            feature_link.delete()

                    if not feature_link and not data.get('DELETE'):
                        FeatureLink.objects.create(
                            relation_type=data.get('relation_type'),
                            feature_from=feature,
                            feature_to=data.get('feature_to'))

                # Traitement des piéces jointes
                for data in attachment_formset.cleaned_data:

                    attachment = data.pop('id', None)

                    if attachment and data.get('DELETE'):
                        attachment.delete()

                    if attachment and not data.get('DELETE'):
                        attachment.attachment_file = data.get(
                            'attachment_file')
                        attachment.title = data.get('title')
                        attachment.info = data.get('info')
                        attachment.save()

                    if not attachment and not data.get('DELETE'):
                        Attachment.objects.create(
                            attachment_file=data.get('attachment_file'),
                            title=data.get('title'),
                            info=data.get('info'),
                            object_type='feature',
                            project=project,
                            feature_id=feature.feature_id,
                            author=user,
                        )

                messages.info(
                    request, "Le signalement {title} a bien été créé. ".format(
                        title=feature.title, ))

                return redirect('geocontrib:feature_detail',
                                slug=project.slug,
                                feature_type_slug=feature_type.slug,
                                feature_id=feature.feature_id)

        else:
            logger.error([ff.errors for ff in all_forms])

        linked_formset = self.LinkedFormset(
            request.POST or None,
            prefix='linked',
            form_kwargs={'feature_type': feature_type},
        )

        attachment_formset = self.AttachmentFormset(request.POST or None,
                                                    request.FILES,
                                                    prefix='attachment')

        context = {
            **self.get_context_data(),
            **{
                'features':
                Feature.handy.availables(user, project).order_by('updated_on'),
                'feature_type':
                feature_type,
                'project':
                project,
                'permissions':
                permissions,
                'feature_form':
                feature_form,
                'extra_form':
                extra_form,
                'linked_formset':
                linked_formset,
                'attachment_formset':
                attachment_formset,
                'action':
                'create',
            }
        }
        return render(request, 'geocontrib/feature/feature_edit.html', context)
예제 #10
0
    def ping_users(self, *args, **kwargs):
        """
        Les différents cas d'envoi de notifications sont :
            - Les modérateurs d’un projet sont notifiés des signalements dont le statut
            devient "pending" (en attente de publication).
            Cela n'a de sens que pour les projets qui sont modérés.

            - L'auteur d'un signalement est notifié des changements de statut du signalement,
            des modifications du signalement et de l’ajout de commentaires
            (si l'auteur n'est pas lui-même à l'origine de ces évènements).

            - Un utilisateur abonné à un projet est notifié de tout évènement
            (dont il n'est pas à l'origine) sur ce projet.
        """
        event_initiator = self.user

        if self.object_type == 'feature':
            Feature = apps.get_model(app_label='geocontrib',
                                     model_name='Feature')
            feature = Feature.objects.get(feature_id=self.feature_id)
            project = feature.project
            if project.moderation:

                # On notifie les modérateurs du projet si l'evenement concerne
                # Un demande de publication d'un signalement
                feature_status = self.data.get('feature_status', {})
                status_has_changed = feature_status.get('has_changed', False)
                new_status = feature_status.get('new_status', 'draft')

                if status_has_changed and new_status == 'pending':
                    Authorization = apps.get_model(app_label='geocontrib',
                                                   model_name='Authorization')
                    UserLevelPermission = apps.get_model(
                        app_label='geocontrib',
                        model_name='UserLevelPermission')
                    moderateur_rank = UserLevelPermission.objects.get(
                        user_type_id=MODERATOR).rank
                    moderators__emails = Authorization.objects.filter(
                        project=project, level__rank__gte=moderateur_rank
                    ).exclude(
                        user=
                        event_initiator  # On exclue l'initiateur de l'evenement.
                    ).values_list('user__email', flat=True)

                    context = {
                        'feature': feature,
                        'event_initiator': event_initiator,
                        'application_name': settings.APPLICATION_NAME,
                        'application_abstract': settings.APPLICATION_ABSTRACT,
                    }
                    logger.debug(moderators__emails)
                    try:
                        notif_moderators_pending_features(
                            emails=moderators__emails, context=context)
                    except Exception:
                        logger.exception('Event.ping_users')

                # On notifie l'auteur du signalement si l'evenement concerne
                # la publication de son signalement
                if status_has_changed and new_status == 'published':
                    if event_initiator != feature.creator:
                        context = {'feature': feature, 'event': self}
                        try:
                            notif_creator_published_feature(emails=[
                                feature.creator.email,
                            ],
                                                            context=context)
                        except Exception:
                            logger.exception(
                                'Event.ping_users.notif_creator_published_feature'
                            )
예제 #11
0
    def post(self, request, slug, feature_type_slug, feature_id):
        feature = self.get_object()
        project = feature.project
        user = request.user
        form = CommentForm(request.POST, request.FILES)

        linked_features = FeatureLink.objects.filter(
            feature_from=feature.feature_id)
        serialized_link = FeatureLinkSerializer(linked_features, many=True)

        if form.is_valid():
            try:
                comment = Comment.objects.create(
                    feature_id=feature.feature_id,
                    feature_type_slug=feature.feature_type.slug,
                    author=user,
                    project=project,
                    comment=form.cleaned_data.get('comment'))
                up_file = form.cleaned_data.get('attachment_file')
                title = form.cleaned_data.get('title')
                info = form.cleaned_data.get('info')
                if comment and up_file and title:
                    Attachment.objects.create(feature_id=feature.feature_id,
                                              author=user,
                                              project=project,
                                              comment=comment,
                                              attachment_file=up_file,
                                              title=title,
                                              info=info,
                                              object_type='comment')

            except Exception as err:
                logger.exception('CommentCreate.post')
                messages.error(
                    request,
                    "Erreur à l'ajout du commentaire: {err}".format(err=err))
            else:
                # Un evenement est ajouter lors de la creation d'un commentaire
                # au niveau des trigger.
                messages.info(request, "Ajout du commentaire confirmé")

            return redirect('geocontrib:feature_detail',
                            slug=slug,
                            feature_type_slug=feature_type_slug,
                            feature_id=feature_id)
        else:
            logger.error(form.errors)

        events = Event.objects.filter(
            feature_id=feature.feature_id).order_by('created_on')
        serialized_events = EventSerializer(events, many=True)

        context = {
            **self.get_context_data(),
            **{
                'feature':
                feature,
                'feature_data':
                feature.custom_fields_as_list,
                'feature_types':
                FeatureType.objects.filter(project=project),
                'feature_type':
                feature.feature_type,
                'linked_features':
                serialized_link.data,
                'project':
                project,
                'permissions':
                Authorization.all_permissions(user, project, feature),
                'comments':
                Comment.objects.filter(project=project,
                                       feature_id=feature.feature_id),
                'attachments':
                Attachment.objects.filter(project=project,
                                          feature_id=feature.feature_id,
                                          object_type='feature'),
                'events':
                serialized_events.data,
                'comment_form':
                form,
            }
        }

        return render(request, 'geocontrib/feature/feature_detail.html',
                      context)