Beispiel #1
0
    def get(self, request, format=None):
        resp = OrderedDict()
        errors = []

        for model_cls, url_name_dict in MODEL_VIEW_DICT.iteritems():
            try:
                resp[model_cls._meta.verbose_name] = _lookup_metadata(url_name_dict, request, model_cls, self)
            except Exception as e:
                # There is a good reason for this broad catch
                # Accumulate and report all errors at once ( re-raising )
                LOGGER.exception(e)
                errors.append(e)

        if errors:  # See, our broad Except up there wasn't so evil after all
            raised_exc = ValidationError(detail=errors)
            raised_exc.message = "Could not create root / metadata view"
            raise raised_exc

        return Response(resp)
 def validate(self, attrs):
     super(ConditionSerializer, self).validate(attrs)
     if attrs.get('operator') != models.PERCENTAGE_SPLIT and not attrs.get('property'):
         raise ValidationError({'property': ['This field may not be blank.']})
     return attrs
Beispiel #3
0
 def validate(self, data):
     email = data['email']
     user_qs = User.objects.filter(email=email)
     if user_qs.exists():
         raise ValidationError("This mail has already registered.")
     return data
Beispiel #4
0
    def update_or_create_reverse_relations(self, instance, reverse_relations):
        # Update or create reverse relations:
        # many-to-one, many-to-many, reversed one-to-one
        for field_name, (related_field, field, field_source) in \
                reverse_relations.items():

            # Skip processing for empty data or not-specified field.
            # The field can be defined in validated_data but isn't defined
            # in initial_data (for example, if multipart form data used)
            related_data = self.get_initial().get(field_name, None)
            if related_data is None:
                continue

            if related_field.one_to_one:
                # If an object already exists, fill in the pk so
                # we don't try to duplicate it
                pk_name = field.Meta.model._meta.pk.attname
                if pk_name not in related_data and 'pk' in related_data:
                    pk_name = 'pk'
                if pk_name not in related_data:
                    related_instance = getattr(instance, field_source, None)
                    if related_instance:
                        related_data[pk_name] = related_instance.pk

                # Expand to array of one item for one-to-one for uniformity
                related_data = [related_data]

            instances = self._prefetch_related_instances(field, related_data)

            save_kwargs = self._get_save_kwargs(field_name)
            if isinstance(related_field, GenericRelation):
                save_kwargs.update(
                    self._get_generic_lookup(instance, related_field), )
            elif not related_field.many_to_many:
                save_kwargs[related_field.name] = instance

            new_related_instances = []
            errors = []
            for data in related_data:
                obj = instances.get(
                    self._get_related_pk(data, field.Meta.model))
                serializer = self._get_serializer_for_field(
                    field,
                    instance=obj,
                    data=data,
                )
                try:
                    serializer.is_valid(raise_exception=True)
                    related_instance = serializer.save(**save_kwargs)
                    data['pk'] = related_instance.pk
                    new_related_instances.append(related_instance)
                    errors.append({})
                except ValidationError as exc:
                    errors.append(exc.detail)

            if any(errors):
                if related_field.one_to_one:
                    raise ValidationError({field_name: errors[0]})
                else:
                    raise ValidationError({field_name: errors})

            if related_field.many_to_many:
                # Add m2m instances to through model via add
                m2m_manager = getattr(instance, field_source)
                m2m_manager.add(*new_related_instances)
Beispiel #5
0
    def to_internal_value(self, data):

        content_type = ContentType.objects.get_for_model(
            self.parent.Meta.model)
        custom_fields = {
            field.name: field
            for field in CustomField.objects.filter(obj_type=content_type)
        }

        for field_name, value in data.items():

            try:
                cf = custom_fields[field_name]
            except KeyError:
                raise ValidationError(
                    "Invalid custom field for {} objects: {}".format(
                        content_type, field_name))

            # Data validation
            if value not in [None, '']:

                # Validate integer
                if cf.type == CF_TYPE_INTEGER:
                    try:
                        int(value)
                    except ValueError:
                        raise ValidationError(
                            "Invalid value for integer field {}: {}".format(
                                field_name, value))

                # Validate boolean
                if cf.type == CF_TYPE_BOOLEAN and value not in [
                        True, False, 1, 0
                ]:
                    raise ValidationError(
                        "Invalid value for boolean field {}: {}".format(
                            field_name, value))

                # Validate date
                if cf.type == CF_TYPE_DATE:
                    try:
                        datetime.strptime(value, '%Y-%m-%d')
                    except ValueError:
                        raise ValidationError(
                            "Invalid date for field {}: {}. (Required format is YYYY-MM-DD.)"
                            .format(field_name, value))

                # Validate selected choice
                if cf.type == CF_TYPE_SELECT:
                    try:
                        value = int(value)
                    except ValueError:
                        raise ValidationError(
                            "{}: Choice selections must be passed as integers."
                            .format(field_name))
                    valid_choices = [c.pk for c in cf.choices.all()]
                    if value not in valid_choices:
                        raise ValidationError(
                            "Invalid choice for field {}: {}".format(
                                field_name, value))

            elif cf.required:
                raise ValidationError(
                    "Required field {} cannot be empty.".format(field_name))

        # Check for missing required fields
        missing_fields = []
        for field_name, field in custom_fields.items():
            if field.required and field_name not in data:
                missing_fields.append(field_name)
        if missing_fields:
            raise ValidationError("Missing required fields: {}".format(
                u", ".join(missing_fields)))

        return data
Beispiel #6
0
    def destroy(self, request, *args, **kwargs):
        obj = super().get_object()

        try:
            token = SocialToken.objects.get(
                account__user=request.user, account__provider='github'
            )
        except Exception:
            msg = (
                "Failed to access GitHub account for Galaxy user {}. "
                "You must first authenticate with GitHub."
                .format(request.user.username)
            )
            raise ValidationError(dict(detail=msg))

        gh_api = Github(token.token)

        try:
            gh_repo = gh_api.get_repo(obj.github_user + '/' + obj.github_repo)
        except GithubException as e:
            msg = (
                "GitHub API failed to return repo for {}/{}. {} - {}"
                .format(obj.github_user, obj.github_repo, e.data, e.status)
            )
            raise ValidationError(dict(detail=msg))

        try:
            gh_user = gh_api.get_user()
        except GithubException as e:
            msg = (
                "GitHub API failed to return authorized user. {} - {}"
                .format(e.data, e.status)
            )
            raise ValidationError(dict(detail=msg))

        try:
            gh_user.remove_from_subscriptions(gh_repo)
        except GithubException as e:
            msg = (
                "GitHub API failed to unsubscribe {} from {}/{}. {} - {}"
                .format(request.user.username, obj.github_user,
                        obj.github_repo, e.data, e.status)
            )
            raise ValidationError(dict(detail=msg))

        obj.delete()

        sub_count = 0
        for sub in gh_repo.get_subscribers():
            sub_count += 1   # only way to get subscriber count via pygithub

        repo = models.Repository.objects.get(github_user=obj.github_user,
                                             github_repo=obj.github_repo)
        repo.watchers_count = sub_count
        repo.save()

        result = (
            "unsubscribed {} from {}/{}."
            .format(request.user.username, obj.github_user, obj.github_repo)
        )

        return Response(dict(detail=result), status=status.HTTP_202_ACCEPTED)
Beispiel #7
0
    def post(self, request, *args, **kwargs):
        github_user = request.data.get('github_user')
        github_repo = request.data.get('github_repo')
        github_reference = request.data.get('github_reference', '')
        repository_id = request.data.get('repository_id')

        if not repository_id:
            # request received from old client
            if not github_user or not github_repo:
                raise ValidationError({
                    'detail': "Invalid request. "
                              "Expecting github_user and github_repo."
                })

            namespace = models.ProviderNamespace.objects.get(
                provider__name=constants.PROVIDER_GITHUB,
                name=github_user
            )
            if not request.user.is_staff and \
               not namespace.namespace.owners.filter(
                   username=request.user.get_username()):
                # User is not an onwer of the Namespace
                raise PermissionDenied(
                    "You are not an owner of {0}"
                    .format(namespace.namespace.name)
                )

            try:
                repository = models.Repository.objects.get(
                    provider_namespace=namespace,
                    original_name=github_repo
                )
            except ObjectDoesNotExist:
                repository, created = models.Repository.objects.get_or_create(
                    provider_namespace=namespace,
                    name=sanitize_content_name(github_repo),
                    defaults={
                        'is_enabled': False,
                        'original_name': github_repo,
                        'is_new': True
                    }
                )
        else:
            try:
                repository = models.Repository.objects.get(pk=repository_id)
            except ObjectDoesNotExist:
                raise ValidationError({
                    'detail': "Repository {0} not found, or you do not "
                              "have access".format(repository_id)
                })

            if not request.user.is_staff and \
               not repository.provider_namespace.namespace.owners.filter(
                   username=request.user.get_username()):
                # User is not an onwer of the Namespace
                raise PermissionDenied(
                    "You are not an owner of {0}".format(repository.name)
                )

        task = tasks.create_import_task(
            repository, request.user,
            import_branch=github_reference, user_initiated=True)

        serializer = self.get_serializer(instance=task)
        response = {'results': [serializer.data]}
        return Response(response,
                        status=status.HTTP_201_CREATED,
                        headers=self.get_success_headers(response))
Beispiel #8
0
 def predeploy_validate(self):
     now = timezone.now()
     if self.active_to < now:
         raise ValidationError({'result': 1}, code=400)
Beispiel #9
0
 def validate_type(self, value):
     if value not in ('personal', 'organization'):
         raise ValidationError(
             _("type must be one of 'personal' or 'organization'."))
     return value
Beispiel #10
0
 def validate_plan(self, plan):
     if plan and not plan.is_active:
         raise ValidationError(_("The plan is inactive. "\
             "As a result the coupon will have no effect."))
     return plan
Beispiel #11
0
 def post(self, request, *args, **kwargs):#pylint:disable=unused-argument
     instance = self.get_object()
     if check_has_credentials(request, instance.user):
         raise ValidationError({'detail': _("User is already active")})
     serializer = self.get_serializer(instance)
     return Response(serializer.data)
Beispiel #12
0
    def validate(self, data):
        reservation = self.instance
        request_user = self.context['request'].user

        # this check is probably only needed for PATCH
        try:
            resource = data['resource']
        except KeyError:
            resource = reservation.resource

        if not resource.can_make_reservations(request_user):
            raise PermissionDenied(_('You are not allowed to make reservations in this resource.'))

        if 'end' in data and data['end'] < timezone.now():
            raise ValidationError(_('You cannot make a reservation in the past'))

        if not resource.can_ignore_opening_hours(request_user):
            reservable_before = resource.get_reservable_before()
            if reservable_before and data['begin'] >= reservable_before:
                raise ValidationError(_('The resource is reservable only before %(datetime)s' %
                                        {'datetime': reservable_before}))
            reservable_after = resource.get_reservable_after()
            if reservable_after and data['begin'] < reservable_after:
                raise ValidationError(_('The resource is reservable only after %(datetime)s' %
                                        {'datetime': reservable_after}))

        # normal users cannot make reservations for other people
        if not resource.can_create_reservations_for_other_users(request_user):
            data.pop('user', None)

        # Check user specific reservation restrictions relating to given period.
        resource.validate_reservation_period(reservation, request_user, data=data)

        if data.get('staff_event', False):
            if not resource.can_create_staff_event(request_user):
                raise ValidationError(dict(staff_event=_('Only allowed to be set by resource managers')))

        if 'type' in data:
            if (data['type'] != Reservation.TYPE_NORMAL and
                    not resource.can_create_special_type_reservation(request_user)):
                raise ValidationError({'type': _('You are not allowed to make a reservation of this type')})

        if 'comments' in data:
            if not resource.can_comment_reservations(request_user):
                raise ValidationError(dict(comments=_('Only allowed to be set by staff members')))

        if 'access_code' in data:
            if data['access_code'] is None:
                data['access_code'] = ''

            access_code_enabled = resource.is_access_code_enabled()

            if not access_code_enabled and data['access_code']:
                raise ValidationError(dict(access_code=_('This field cannot have a value with this resource')))

            if access_code_enabled and reservation and data['access_code'] != reservation.access_code:
                raise ValidationError(dict(access_code=_('This field cannot be changed')))

        # Mark begin of a critical section. Subsequent calls with this same resource will block here until the first
        # request is finished. This is needed so that the validations and possible reservation saving are
        # executed in one block and concurrent requests cannot be validated incorrectly.
        Resource.objects.select_for_update().get(pk=resource.pk)

        # Check maximum number of active reservations per user per resource.
        # Only new reservations are taken into account ie. a normal user can modify an existing reservation
        # even if it exceeds the limit. (one that was created via admin ui for example).
        if reservation is None:
            resource.validate_max_reservations_per_user(request_user)

        if self.context['request'] and self.context['request'].method == 'PATCH':
            for key, val in data.items():
                if key not in self.patchable_fields:
                    raise ValidationError(_('Patching of field %(field)s is not allowed' % {'field': key}))
        else:
             # Run model clean
            instance = Reservation(**data)

            try:
                instance.clean(original_reservation=reservation, user=request_user)
            except DjangoValidationError as exc:

                # Convert Django ValidationError to DRF ValidationError so that in the response
                # field specific error messages are added in the field instead of in non_field_messages.
                if not hasattr(exc, 'error_dict'):
                    raise ValidationError(exc)
                error_dict = {}
                for key, value in exc.error_dict.items():
                    error_dict[key] = [error.message for error in value]
                raise ValidationError(error_dict)
        return data
 def validate_email(self, email):
     if (self.instance is None or self.instance.email != email) and User.objects.filter(email=email).exists():
         raise ValidationError("El email {0} ya está en uso".format(email))
     return email.lower()
 def validate_username(self, username):
     if (self.instance is None or self.instance.username != username) and User.objects.filter(username=username).exists():
         raise ValidationError("El nombre de usuario {0} no está disponible".format(username))
     return username
Beispiel #15
0
 def get_object(self):
     if self.request.data.get('id'):
         return self.queryset.get(id=self.request.data['id'])
     raise ValidationError("id must be provided", "required")
 def delete(self, request, *args, **kwargs):
     if self.get_queryset().exists():
         self.get_queryset().delete()
         return Response(status=status.HTTP_204_NO_CONTENT)
     else:
         raise ValidationError('You never voted for this post!')
Beispiel #17
0
    def update(self, instance, validated_data):

        LIMITED_RECIEVING_STATUS_ = [
            "DESTINATION APPROVED",
            "DESTINATION REJECTED",
            "COMPLETED",
        ]
        LIMITED_RECIEVING_STATUS = [
            REVERSE_SHIFTING_STATUS_CHOICES[x]
            for x in LIMITED_RECIEVING_STATUS_
        ]
        LIMITED_SHIFTING_STATUS_ = [
            "APPROVED",
            "REJECTED",
            "PATIENT TO BE PICKED UP",
            "TRANSPORTATION TO BE ARRANGED",
            "TRANSFER IN PROGRESS",
            "COMPLETED",
            "PENDING",
            "ON HOLD",
        ]
        LIMITED_SHIFTING_STATUS = [
            REVERSE_SHIFTING_STATUS_CHOICES[x]
            for x in LIMITED_SHIFTING_STATUS_
        ]
        LIMITED_ORGIN_STATUS = []

        RECIEVING_REQUIRED_STATUS_ = [
            "DESTINATION APPROVED",
            "DESTINATION REJECTED",
            "TRANSPORTATION TO BE ARRANGED",
            "PATIENT TO BE PICKED UP",
            "TRANSFER IN PROGRESS",
            "COMPLETED",
        ]
        RECIEVING_REQUIRED_STATUS = [
            REVERSE_SHIFTING_STATUS_CHOICES[x]
            for x in RECIEVING_REQUIRED_STATUS_
        ]

        user = self.context["request"].user

        if "is_kasp" in validated_data:
            if validated_data[
                    "is_kasp"] != instance.is_kasp:  # Check only when changed
                if not has_facility_permission(
                        user, instance.shifting_approving_facility):
                    raise ValidationError({"kasp": ["Permission Denied"]})

        if "status" in validated_data:
            if validated_data["status"] in LIMITED_RECIEVING_STATUS:
                if instance.assigned_facility:
                    if not has_facility_permission(user,
                                                   instance.assigned_facility):
                        raise ValidationError(
                            {"status": ["Permission Denied"]})
            elif validated_data["status"] in LIMITED_SHIFTING_STATUS:
                if not has_facility_permission(
                        user, instance.shifting_approving_facility):
                    raise ValidationError({"status": ["Permission Denied"]})

        # Dont allow editing origin or patient
        if "orgin_facility" in validated_data:
            validated_data.pop("orgin_facility")
        if "patient" in validated_data:
            validated_data.pop("patient")

        if "shifting_approving_facility" in validated_data:
            shifting_approving_facility_external_id = validated_data.pop(
                "shifting_approving_facility")["external_id"]
            if shifting_approving_facility_external_id:
                validated_data[
                    "shifting_approving_facility_id"] = Facility.objects.get(
                        external_id=shifting_approving_facility_external_id).id

        assigned = False
        if "assigned_facility" in validated_data:
            assigned_facility_external_id = validated_data.pop(
                "assigned_facility")["external_id"]
            if assigned_facility_external_id:
                validated_data["assigned_facility_id"] = Facility.objects.get(
                    external_id=assigned_facility_external_id).id
                assigned = True

        if "status" in validated_data:
            if validated_data["status"] in RECIEVING_REQUIRED_STATUS:
                if (not instance.assigned_facility) and (not assigned):
                    raise ValidationError({
                        "status": [
                            "Destination Facility is required for moving to this stage."
                        ]
                    })

        instance.last_edited_by = self.context["request"].user

        old_status = instance.status

        new_instance = super().update(instance, validated_data)

        if "status" in validated_data:
            if validated_data["status"] != old_status:
                if validated_data["status"] == 40:
                    NotificationGenerator(
                        event=Notification.Event.SHIFTING_UPDATED,
                        caused_by=self.context["request"].user,
                        caused_object=ShiftingRequest.objects.get(
                            id=new_instance.id),
                        facility=new_instance.shifting_approving_facility,
                        notification_mediums=[
                            Notification.Medium.SYSTEM, Notification.Medium.SMS
                        ],
                    ).generate()

        return new_instance
Beispiel #18
0
 def validate(self, data):
     full_data = self.to_internal_value(self.to_representation(self.instance)) if self.instance else {}
     full_data.update(data)
     if full_data.get('limit_events') and full_data.get('all_events'):
         raise ValidationError('Do not set both limit_events and all_events.')
     return data
Beispiel #19
0
 def validate_old_password(self, value):
     user = self.user_handler.get_by_id(self.context.get('request').user.id)
     if user.check_password('{}'.format(value)):
         return value
     raise ValidationError(_("Wrong password."))
Beispiel #20
0
    def post(self, request, *args, **kwargs):
        github_user = request.data.get('github_user', None)
        github_repo = request.data.get('github_repo', None)

        if not github_user or not github_repo:
            raise ValidationError({
                'detail': "Invalid request. "
                          "Missing one or more required values."
            })

        try:
            token = SocialToken.objects.get(
                account__user=request.user,
                account__provider='github'
            )
        except Exception:
            msg = (
                "Failed to connect to GitHub account for Galaxy user {}. "
                "You must first authenticate with Github."
                .format(request.user.username)
            )
            raise ValidationError(dict(detail=msg))

        gh_api = Github(token.token)

        try:
            gh_repo = gh_api.get_repo(github_user + '/' + github_repo)
        except GithubException as e:
            msg = (
                "GitHub API failed to return repo for {}/{}. {} - {}"
                .format(github_user, github_repo, e.data, e.status)
            )
            raise ValidationError(dict(detail=msg))

        try:
            gh_user = gh_api.get_user()
        except GithubException as e:
            msg = (
                "GitHub API failed to return authorized user. {} - {}"
                .format(e.data, e.status)
            )
            raise ValidationError(dict(detail=msg))

        try:
            gh_user.add_to_subscriptions(gh_repo)
        except GithubException:
            msg = (
                "GitHub API failed to subscribe user {} to for {}/{}"
                .format(request.user.username, github_user, github_repo)
            )
            raise ValidationError(dict(detail=msg))

        new_sub, created = models.Subscription.objects.get_or_create(
            owner=request.user,
            github_user=github_user,
            github_repo=github_repo,
            defaults={
                'owner': request.user,
                'github_user': github_user,
                'github_repo': github_repo
            })

        sub_count = 0
        for s in gh_repo.get_subscribers():
            sub_count += 1   # only way to get subscriber count via pygithub

        repo = models.Repository.objects.get(github_user=github_user,
                                             github_repo=github_repo)
        repo.watchers_count = sub_count
        repo.save()

        return Response(dict(
            result=dict(
                id=new_sub.id,
                github_user=new_sub.github_user,
                github_repo=new_sub.github_repo,
                watchers_count=sub_count
            )
        ), status=status.HTTP_201_CREATED)
Beispiel #21
0
 def perform_create(self, serializer):
     """set a current logged in user automatically"""
     try:
         serializer.save(askFrom=self.request.user)
     except:
         raise ValidationError("User can have only unique request")
Beispiel #22
0
    def delete(self, request, *args, **kwargs):

        gh_user = request.query_params.get('github_user', None)
        gh_repo = request.query_params.get('github_repo', None)

        if not gh_user or not gh_repo:
            raise ValidationError(dict(detail="Invalid request."))

        if not request.user.is_staff:
            # Verify via GitHub API that user has access to requested role
            try:
                token = SocialToken.objects.get(
                    account__user=request.user, account__provider='github'
                )
            except Exception:
                msg = (
                    "Failed to get Github account for Galaxy user {}. "
                    "You must first authenticate with Github."
                    .format(request.user.username)
                )
                raise ValidationError({'detail': msg})

            gh_api = Github(token.token)

            try:
                ghu = gh_api.get_user()
            except Exception:
                raise ValidationError(
                    {'detail': "Failed to get Github authorized user."}
                )

            allowed = False
            repo_full_name = "{}/{}".format(gh_user, gh_repo)
            for r in ghu.get_repos():
                if r.full_name == repo_full_name:
                    allowed = True
                    continue

            if not allowed:
                msg = (
                    "Galaxy user {0} does not have access to repo {1}"
                    .format(request.user.username, repo_full_name)
                )
                raise ValidationError(dict(detail=msg))

        # User has access. Delete requested role and associated bits.
        response = OrderedDict([
            ('deleted_roles', []),
            ('status', '')
        ])

        roles = models.Content.objects.filter(
            repository__provider_namespace__name=gh_user,
            repository__original_name=gh_repo)
        cnt = len(roles)
        if cnt == 0:
            response['status'] = (
                "Role {}.{} not found. Maybe it was deleted previously?"
                .format(gh_user, gh_repo)
            )
            return Response(response)
        elif cnt == 1:
            response['status'] = "Role {}.{} deleted".format(gh_user, gh_repo)
        else:
            response['status'] = (
                "Deleted {:d} roles associated with {}/{}"
                .format(len(roles), gh_user, gh_repo)
            )

        for role in roles:
            response['deleted_roles'].append({
                "id": role.id,
                "namespace": role.namespace.name,
                "name": role.name,
                "github_user": role.github_user,
                "github_repo": role.github_repo
            })

        repo = models.Repository.objects.get(
            provider_namespace__name=gh_user,
            original_name=gh_repo)

        models.Notification.objects.filter(repository=repo).delete()
        models.Content.objects.filter(repository=repo).delete()
        models.ImportTask.objects.filter(repository=repo).delete()
        repo.delete()

        return Response(response)
Beispiel #23
0
 def validate_rrule(self, value):
     try:
         rrulestr(value)
     except ValueError as e:
         raise ValidationError(str(e))
     return value
 def validate(self, attrs):
     if attrs['password'] != attrs['password2']:
         raise ValidationError('两次密码不一致')
     return attrs
Beispiel #25
0
 def validate(self, data, user=None):
     """Validate password"""
     if not re.findall('[0-9]', data):
         raise ValidationError(dict(
             password="******"),
                               code='password_no_digit')
Beispiel #26
0
 def __call__(self, value):
     if '![' in value:
         raise ValidationError('Images not supported in markdown')
Beispiel #27
0
def is_reserved(request, idx):
	parkSpot = Spot.objects.get(identity=idx)
	if not parkSpot:
		raise ValidationError("Could not find spot with id: " + str(idx))
	return JsonResponse({"reserved": parkSpot.reserved})
Beispiel #28
0
def validate_date(value):
    current_year = int(date.today().year)
    if value > current_year or value <= 0:
        raise ValidationError('Wrong date!')
Beispiel #29
0
    def geometries(self, request, update_cache_key, update_cache_key_match, *args, **kwargs):
        Level = request.changeset.wrap_model('Level')
        Space = request.changeset.wrap_model('Space')
        Column = request.changeset.wrap_model('Column')
        Hole = request.changeset.wrap_model('Hole')
        AltitudeMarker = request.changeset.wrap_model('AltitudeMarker')
        Building = request.changeset.wrap_model('Building')
        Door = request.changeset.wrap_model('Door')
        LocationGroup = request.changeset.wrap_model('LocationGroup')
        WifiMeasurement = request.changeset.wrap_model('WifiMeasurement')

        level = request.GET.get('level')
        space = request.GET.get('space')
        if level is not None:
            if space is not None:
                raise ValidationError('Only level or space can be specified.')

            level = get_object_or_404(Level.objects.filter(Level.q_for_request(request)), pk=level)

            edit_utils = LevelChildEditUtils(level, request)
            if not edit_utils.can_access_child_base_mapdata:
                raise PermissionDenied

            levels, levels_on_top, levels_under = self._get_levels_pk(request, level)
            # don't prefetch groups for now as changesets do not yet work with m2m-prefetches
            levels = Level.objects.filter(pk__in=levels).filter(Level.q_for_request(request))
            # graphnodes_qs = request.changeset.wrap_model('GraphNode').objects.all()
            levels = levels.prefetch_related(
                Prefetch('spaces', Space.objects.filter(Space.q_for_request(request)).only(
                    'geometry', 'level', 'outside'
                )),
                Prefetch('doors', Door.objects.filter(Door.q_for_request(request)).only('geometry', 'level')),
                Prefetch('spaces__columns', Column.objects.filter(
                    Q(access_restriction__isnull=True) | ~Column.q_for_request(request)
                ).only('geometry', 'space')),
                Prefetch('spaces__groups', LocationGroup.objects.only(
                    'color', 'category', 'priority', 'hierarchy', 'category__priority', 'category__allow_spaces'
                )),
                Prefetch('buildings', Building.objects.only('geometry', 'level')),
                Prefetch('spaces__holes', Hole.objects.only('geometry', 'space')),
                Prefetch('spaces__altitudemarkers', AltitudeMarker.objects.only('geometry', 'space')),
                Prefetch('spaces__wifi_measurements', WifiMeasurement.objects.only('geometry', 'space')),
                # Prefetch('spaces__graphnodes', graphnodes_qs)
            )

            levels = {s.pk: s for s in levels}

            level = levels[level.pk]
            levels_under = [levels[pk] for pk in levels_under]
            levels_on_top = [levels[pk] for pk in levels_on_top]

            # todo: permissions
            # graphnodes = tuple(chain(*(space.graphnodes.all()
            #                            for space in chain(*(level.spaces.all() for level in levels.values())))))
            # graphnodes_lookup = {node.pk: node for node in graphnodes}

            # graphedges = request.changeset.wrap_model('GraphEdge').objects.all()
            # graphedges = graphedges.filter(Q(from_node__in=graphnodes) | Q(to_node__in=graphnodes))
            # graphedges = graphedges.select_related('waytype')

            # this is faster because we only deserialize graphnode geometries once
            # missing_graphnodes = graphnodes_qs.filter(pk__in=set(chain(*((edge.from_node_id, edge.to_node_id)
            #                                                              for edge in graphedges))))
            # graphnodes_lookup.update({node.pk: node for node in missing_graphnodes})
            # for edge in graphedges:
            #     edge._from_node_cache = graphnodes_lookup[edge.from_node_id]
            #     edge._to_node_cache = graphnodes_lookup[edge.to_node_id]

            # graphedges = [edge for edge in graphedges if edge.from_node.space_id != edge.to_node.space_id]

            results = chain(
                *(self._get_level_geometries(l) for l in levels_under),
                self._get_level_geometries(level),
                *(self._get_level_geometries(l) for l in levels_on_top),
                *(space.altitudemarkers.all() for space in level.spaces.all()),
                *(space.wifi_measurements.all() for space in level.spaces.all())
                # graphedges,
                # graphnodes,
            )
        elif space is not None:
            space_q_for_request = Space.q_for_request(request)
            qs = Space.objects.filter(space_q_for_request)
            space = get_object_or_404(qs.select_related('level', 'level__on_top_of'), pk=space)
            level = space.level

            edit_utils = SpaceChildEditUtils(space, request)
            if not edit_utils.can_access_child_base_mapdata:
                raise PermissionDenied

            if request.user_permissions.can_access_base_mapdata:
                doors = [door for door in level.doors.filter(Door.q_for_request(request)).all()
                         if door.geometry.intersects(space.geometry)]
                doors_space_geom = cascaded_union([door.geometry for door in doors]+[space.geometry])

                levels, levels_on_top, levels_under = self._get_levels_pk(request, level.primary_level)
                if level.on_top_of_id is not None:
                    levels = chain([level.pk], levels_on_top)
                other_spaces = Space.objects.filter(space_q_for_request, level__pk__in=levels).only(
                    'geometry', 'level'
                ).prefetch_related(
                    Prefetch('groups', LocationGroup.objects.only(
                        'color', 'category', 'priority', 'hierarchy', 'category__priority', 'category__allow_spaces'
                    ).filter(color__isnull=False))
                )

                space = next(s for s in other_spaces if s.pk == space.pk)
                other_spaces = [s for s in other_spaces
                                if s.geometry.intersects(doors_space_geom) and s.pk != space.pk]
                all_other_spaces = other_spaces

                if level.on_top_of_id is None:
                    other_spaces_lower = [s for s in other_spaces if s.level_id in levels_under]
                    other_spaces_upper = [s for s in other_spaces if s.level_id in levels_on_top]
                else:
                    other_spaces_lower = [s for s in other_spaces if s.level_id == level.on_top_of_id]
                    other_spaces_upper = []
                other_spaces = [s for s in other_spaces if s.level_id == level.pk]

                space.bounds = True

                # deactivated for performance reasons
                buildings = level.buildings.all()
                # buildings_geom = cascaded_union([building.geometry for building in buildings])
                # for other_space in other_spaces:
                #     if other_space.outside:
                #         other_space.geometry = other_space.geometry.difference(buildings_geom)
                for other_space in chain(other_spaces, other_spaces_lower, other_spaces_upper):
                    other_space.opacity = 0.4
                    other_space.color = '#ffffff'
                for building in buildings:
                    building.opacity = 0.5
            else:
                buildings = []
                doors = []
                other_spaces = []
                other_spaces_lower = []
                other_spaces_upper = []
                all_other_spaces = []

            # todo: permissions
            if request.user_permissions.can_access_base_mapdata:
                graphnodes = request.changeset.wrap_model('GraphNode').objects.all()
                graphnodes = graphnodes.filter((Q(space__in=all_other_spaces)) | Q(space__pk=space.pk))

                space_graphnodes = tuple(node for node in graphnodes if node.space_id == space.pk)

                graphedges = request.changeset.wrap_model('GraphEdge').objects.all()
                space_graphnodes_ids = tuple(node.pk for node in space_graphnodes)
                graphedges = graphedges.filter(Q(from_node__pk__in=space_graphnodes_ids) |
                                               Q(to_node__pk__in=space_graphnodes_ids))
                graphedges = graphedges.select_related('from_node', 'to_node', 'waytype').only(
                    'from_node__geometry', 'to_node__geometry', 'waytype__color'
                )
            else:
                graphnodes = []
                graphedges = []

            areas = space.areas.filter(Area.q_for_request(request)).only(
                'geometry', 'space'
            ).prefetch_related(
                Prefetch('groups', LocationGroup.objects.order_by(
                    '-category__priority', '-hierarchy', '-priority'
                ).only(
                    'color', 'category', 'priority', 'hierarchy', 'category__priority', 'category__allow_areas'
                ))
            )
            for area in areas:
                area.opacity = 0.5
            areas = sorted(areas, key=self.area_sorting_func)

            results = chain(
                buildings,
                other_spaces_lower,
                doors,
                other_spaces,
                [space],
                areas,
                space.holes.all().only('geometry', 'space'),
                space.stairs.all().only('geometry', 'space'),
                space.ramps.all().only('geometry', 'space'),
                space.obstacles.all().only('geometry', 'space', 'color'),
                space.lineobstacles.all().only('geometry', 'width', 'space', 'color'),
                space.columns.all().only('geometry', 'space'),
                space.altitudemarkers.all().only('geometry', 'space'),
                space.wifi_measurements.all().only('geometry', 'space'),
                space.pois.filter(POI.q_for_request(request)).only('geometry', 'space').prefetch_related(
                    Prefetch('groups', LocationGroup.objects.only(
                        'color', 'category', 'priority', 'hierarchy', 'category__priority', 'category__allow_pois'
                    ).filter(color__isnull=False))
                ),
                other_spaces_upper,
                graphedges,
                graphnodes
            )
        else:
            raise ValidationError('No level or space specified.')

        return Response(list(chain(
            [('update_cache_key', update_cache_key)],
            (self.conditional_geojson(obj, update_cache_key_match) for obj in results)
        )))
 def perform_create(self, serializer):
     if self.get_queryset().exists():
         raise ValidationError('You have already vote for this post :)')
     serializer.save(voter=self.request.user,
                     post=Post.objects.get(pk=self.kwargs['pk']))
Beispiel #31
0
 def validate(self, attrs):
     if self.initial_data.get(
             'check_specification') and not attrs.get('content'):
         raise ValidationError('Experiment group expects `content`.')
     return attrs