from apollo_utils.service.schemas.base import RequestSchema from apollo_utils.service.schemas.fields.enum import EnumField from marshmallow import Schema, ValidationError, fields, validate, validates_schema from server.constants.messages import MESSAGES_CHUNK_MAX_SIZE, PushMessageOuterStatus, PushMessagePriority from server.schemas.messages import mixins from server.schemas.messages.base import BaseMessageBulkCreateResponse, BaseMessageCreateRequestItem, \ BaseMessageListRequest, BaseMessageListResponseItem from server.schemas.messages.fields import BulkField class PushMessageMixin: to = fields.Str(required=True) title = fields.Str(default=None) body = fields.Str(default=None) sound = fields.Str(default="default") expiration = fields.Float(default=None) priority = EnumField(PushMessagePriority, missing=PushMessagePriority.DEFAULT) badge = fields.Int(default=None) category = fields.Str(default=None) channel_id = fields.Str(missing="all", default=None) display_in_foreground = fields.Bool(missing=False) class PushMessages: """Schemas class for push messages api.""" class List: class Request(BaseMessageListRequest): pass class Response(mixins.ListToDataDumpMixin, Schema): class Item(mixins.DeviceIdNoneMixin, PushMessageMixin, BaseMessageListResponseItem): status = fields.Function(lambda obj: obj.status.name.lower()) priority = fields.Function(lambda obj: obj.priority.name.lower()) receipt = fields.Str(default=None) data = fields.List(fields.Nested(Item)) class CreateBulk: class Request(mixins.PublicMixin, RequestSchema): class Item(mixins.DeviceIdNoneMixin, PushMessageMixin, BaseMessageCreateRequestItem): pass data = BulkField( fields.Nested(Item), required=True, validate=validate.Length(min=1, max=MESSAGES_CHUNK_MAX_SIZE) ) class Response(BaseMessageBulkCreateResponse): pass class UpdateBulk: class Request(RequestSchema): class Item(RequestSchema): _id = fields.Int(required=True, data_key="id") status = EnumField(PushMessageOuterStatus, required=True, load_as="name") receipt = fields.String(missing=None) receipt_id = fields.String(missing=None) @validates_schema def validate_status(self, data, **kwargs): if data["status"] == PushMessageOuterStatus.FAILED.name and not data.get("receipt"): raise ValidationError("Receipt is required for 'failed' push messages.") data = fields.List( fields.Nested(Item), required=True, validate=validate.Length(min=1, max=MESSAGES_CHUNK_MAX_SIZE) )