class UserPresenceSchema(Schema): uuid = fields.UUID(dump_only=True) tenant_uuid = fields.UUID(dump_only=True) state = fields.String( required=True, validate=OneOf(['available', 'unavailable', 'invisible', 'away'])) status = fields.String(allow_none=True) last_activity = fields.DateTime(dump_only=True) line_state = fields.String(dump_only=True) mobile = fields.Boolean(dump_only=True) do_not_disturb = fields.Boolean(dump_only=True) connected = fields.Boolean(dump_only=True) lines = fields.Nested('LinePresenceSchema', many=True, dump_only=True) @post_dump def _set_line_state(self, user, **kwargs): line_states = [line['state'] for line in user['lines']] if 'ringing' in line_states: merged_state = 'ringing' elif 'progressing' in line_states: merged_state = 'progressing' elif 'holding' in line_states: merged_state = 'holding' elif 'talking' in line_states: merged_state = 'talking' elif 'available' in line_states: merged_state = 'available' else: merged_state = 'unavailable' user['line_state'] = merged_state return user @post_dump(pass_original=True) def _set_mobile(self, user, raw_user, **kwargs): for token in raw_user.refresh_tokens: if token.mobile is True: user['mobile'] = True return user for session in raw_user.sessions: if session.mobile is True: user['mobile'] = True return user user['mobile'] = False return user @post_dump(pass_original=True) def _set_connected(self, user, raw_user, **kwargs): user['connected'] = True if raw_user.sessions else False return user
class ParticipantSchema(Schema): class Meta: strict = True ordered = True id = fields.String() caller_id_name = fields.String() caller_id_number = fields.String() muted = fields.Boolean() join_time = fields.Integer() admin = fields.Boolean() language = fields.String() call_id = fields.String()
class ParticipantSchema(Schema): class Meta: ordered = True unknown = EXCLUDE id = fields.String() caller_id_name = fields.String() caller_id_number = fields.String() muted = fields.Boolean() join_time = fields.Integer() admin = fields.Boolean() language = fields.String() call_id = fields.String() user_uuid = fields.String(allow_none=True)
class ListSchema(_ListSchema): searchable_columns = ['uuid', 'name'] sort_columns = ['name'] default_sort_column = 'name' recurse = fields.Boolean(missing=False)
class ContactListSchema(_ListSchema): searchable_columns = ['uuid', 'firstname', 'lastname'] sort_columns = ['firstname', 'lastname'] default_sort_column = 'firstname' recurse = fields.Boolean(missing=False)
class RefreshTokenSchema(BaseSchema): client_id = xfields.String(min=1, max=1024) created_at = xfields.DateTime() mobile = xfields.Boolean() user_uuid = xfields.String() tenant_uuid = xfields.String()
class ConfdConfigSchema(BaseSchema): host = fields.String(validate=Length(min=1, max=1024), missing='localhost') port = fields.Integer(validate=Range(min=1, max=65535), missing=9486) verify_certificate = VerifyCertificateField(missing=True) timeout = fields.Float(validate=Range(min=0, max=3660)) https = fields.Boolean(missing=True) version = fields.String(validate=Length(min=1, max=16), missing='1.1')
class MarketListRequestSchema(Schema): direction = fields.String(validate=OneOf(['asc', 'desc']), missing='asc') order = fields.String(validate=Length(min=1), missing='name') limit = fields.Integer(validate=Range(min=0), missing=None) offset = fields.Integer(validate=Range(min=0), missing=0) search = fields.String(missing=None) installed = fields.Boolean()
class BaseAuthConfigSchema(BaseSchema): host = fields.String(validate=Length(min=1, max=1024), missing='localhost') port = fields.Integer(validate=Range(min=1, max=65535), missing=443) https = fields.Boolean(missing=True) verify_certificate = VerifyCertificateField(missing=True) prefix = fields.String(allow_none=True, missing='/api/auth') version = fields.String(validate=Length(min=1, max=16), missing='0.1') timeout = fields.Float(validate=Range(min=0, max=3660))
class ListSchema(BaseSchema): limit = fields.Integer(validate=validate.Range(min=0)) offset = fields.Integer(validate=validate.Range(min=0)) search = fields.String() recurse = fields.Boolean() class Meta: unknown = marshmallow.INCLUDE
class _BaseUserSchema(BaseSchema): username = fields.String(validate=validate.Length(min=1, max=256), required=True) firstname = fields.String(missing=None, allow_none=True) lastname = fields.String(missing=None, allow_none=True) purpose = fields.String(missing='user', validate=validate.OneOf( ['user', 'internal', 'external_api'])) enabled = fields.Boolean(missing=True)
class ListRequestSchema(Schema): recurse = fields.Boolean(missing=False) user_uuid = fields.List(fields.UUID(), missing=[], attribute='uuids') @pre_load def convert_user_uuid_to_list(self, data, **kwargs): result = data.to_dict() if data.get('user_uuid'): result['user_uuid'] = data['user_uuid'].split(',') return result
class PolicyFullSchema(BaseSchema): uuid = fields.String(dump_only=True) tenant_uuid = fields.String(dump_only=True, attribute='tenant_uuid_exposed') name = fields.String(validate=validate.Length(min=1, max=80), required=True) slug = fields.String( validate=[validate.Length(min=1, max=80), validate.Regexp(SLUG_REGEX)], missing=None, ) description = fields.String(allow_none=True, missing=None) acl = fields.List(fields.String(), missing=[], attribute='acl') read_only = fields.Boolean(dump_only=True) shared = fields.Boolean(missing=False) @post_dump(pass_original=True) def set_shared_exposed_only_for_dump(self, data, original, **kwargs): data['shared'] = original.shared_exposed return data
class PolicyListSchema(BaseListSchema): read_only = fields.Boolean() sort_columns = ['name', 'slug', 'description', 'uuid', 'read_only'] default_sort_column = 'name' searchable_columns = [ 'uuid', 'name', 'slug', 'user_uuid', 'group_uuid', 'tenant_uuid', 'read_only', ]
class CDRSchema(Schema): id = fields.Integer() tenant_uuid = fields.UUID() start = fields.DateTime(attribute='date') end = fields.DateTime(attribute='date_end') answered = fields.Boolean(attribute='marshmallow_answered') answer = fields.DateTime(attribute='date_answer') duration = fields.TimeDelta(default=None, attribute='marshmallow_duration') call_direction = fields.String(attribute='direction') destination_extension = fields.String(attribute='destination_exten') destination_internal_context = fields.String() destination_internal_extension = fields.String( attribute='destination_internal_exten' ) destination_line_id = fields.Integer() destination_name = fields.String() destination_user_uuid = fields.UUID() requested_name = fields.String() requested_context = fields.String() requested_extension = fields.String(attribute='requested_exten') requested_internal_context = fields.String() requested_internal_extension = fields.String(attribute='requested_internal_exten') source_extension = fields.String(attribute='source_exten') source_internal_context = fields.String() source_internal_name = fields.String() source_internal_extension = fields.String(attribute='source_internal_exten') source_line_id = fields.Integer() source_name = fields.String() source_user_uuid = fields.UUID() tags = fields.List(fields.String(), attribute='marshmallow_tags') recordings = fields.Nested('RecordingSchema', many=True, default=[]) @pre_dump def _compute_fields(self, data, **kwargs): data.marshmallow_answered = True if data.date_answer else False if data.date_answer and data.date_end: data.marshmallow_duration = data.date_end - data.date_answer return data @post_dump def fix_negative_duration(self, data, **kwargs): if data['duration'] is not None: data['duration'] = max(data['duration'], 0) return data @pre_dump def _populate_tags_field(self, data, **kwargs): data.marshmallow_tags = set() for participant in data.participants: data.marshmallow_tags.update(participant.tags) return data
class CDRListRequestSchema(CDRListingBase): direction = fields.String(validate=OneOf(['asc', 'desc']), missing='desc') order = fields.String( validate=OneOf(set(CDRSchema().fields) - {'end', 'tags', 'recordings'}), missing='start', ) limit = fields.Integer(validate=Range(min=0), missing=1000) offset = fields.Integer(validate=Range(min=0), missing=None) distinct = fields.String(validate=OneOf(['peer_exten']), missing=None) recorded = fields.Boolean(missing=None) format = fields.String(validate=OneOf(['csv', 'json']), missing=None) @post_load def map_order_field(self, in_data, **kwargs): mapped_order = CDRSchema().fields[in_data['order']].attribute if mapped_order: in_data['order'] = mapped_order return in_data
class SubscriptionListParamsSchema(Schema): search_metadata = fields.Dict() recurse = fields.Boolean(missing=False) @pre_load def aggregate_search_metadata(self, data): metadata = {} for search in data.getlist('search_metadata'): try: key, value = search.split(':', 1) except ValueError: continue metadata[key] = value result = {} result['search_metadata'] = metadata if 'recurse' in data: result['recurse'] = data['recurse'] return result
class CDRListingBase(Schema): from_ = fields.DateTime(data_key='from', attribute='start', missing=None) until = fields.DateTime(attribute='end', missing=None) search = fields.String(missing=None) call_direction = fields.String( validate=OneOf(['internal', 'inbound', 'outbound']), missing=None ) number = fields.String(validate=Regexp(NUMBER_REGEX), missing=None) tags = fields.List(fields.String(), missing=[]) user_uuid = fields.List(fields.String(), missing=[], attribute='user_uuids') from_id = fields.Integer(validate=Range(min=0), attribute='start_id', missing=None) recurse = fields.Boolean(missing=False) @pre_load def convert_tags_and_user_uuid_to_list(self, data, **kwargs): result = data.to_dict() if data.get('tags'): result['tags'] = data['tags'].split(',') if data.get('user_uuid'): result['user_uuid'] = data['user_uuid'].split(',') return result
class GroupListSchema(BaseListSchema): read_only = fields.Boolean() sort_columns = ['name', 'uuid', 'read_only'] default_sort_column = 'name' searchable_columns = ['uuid', 'name', 'user_uuid', 'read_only']
class MarketVersionResultSchema(Schema): upgradable = fields.Boolean(required=True) version = fields.String(required=True) min_wazo_version = fields.String() max_wazo_version = fields.String()
class ConfigPatchSchema(Schema): op = fields.String(validate=Equal('replace')) path = fields.String(validate=Equal('/debug')) value = fields.Boolean()
class PluginInstallQueryStringSchema(Schema): reinstall = fields.Boolean(default=False, missing=False)
class _AdminEmailSchema(BaseSchema): address = fields.Email(required=True) confirmed = fields.Boolean(missing=None, allow_none=True) main = fields.Boolean(missing=False)
class SetupSchema(Schema): engine_language = fields.String(required=True, validate=validate.OneOf(['en_US', 'fr_FR'])) engine_password = fields.String(required=True) engine_license = fields.Boolean(required=True, validate=validate.Equal(True)) engine_internal_address = fields.String() engine_instance_uuid = fields.UUID(missing=None) engine_rtp_icesupport = fields.Boolean(required=False, missing=False) engine_rtp_stunaddr = fields.String(validate=validate.Length(min=1, max=1024), missing=None) nestbox_host = fields.String() nestbox_port = fields.Integer( validate=validate.Range(min=0, max=65535, error='Not a valid TCP/IP port number.'), missing=443, ) nestbox_verify_certificate = fields.Boolean(missing=True) nestbox_service_id = fields.String() nestbox_service_key = fields.String() nestbox_instance_name = fields.String() nestbox_engine_host = fields.String() nestbox_engine_port = fields.Integer( validate=validate.Range(min=0, max=65535, error='Not a valid TCP/IP port number.'), missing=443, ) @validates_schema def nestbox_all_or_nothing(self, data): if not data.get('nestbox_host'): return if 'nestbox_service_id' not in data: raise ValidationError( 'Missing keys for Nestbox configuration: nestbox_service_id') if 'nestbox_service_key' not in data: raise ValidationError( 'Missing keys for Nestbox configuration: nestbox_service_key') if 'nestbox_instance_name' not in data: raise ValidationError( 'Missing keys for Nestbox configuration: nestbox_instance_name' ) if 'nestbox_engine_host' not in data: raise ValidationError( 'Missing keys for Nestbox configuration: nestbox_engine_host') if 'engine_internal_address' not in data: raise ValidationError( 'Missing keys for Nestbox configuration: engine_internal_address' ) @validates_schema def check_rtp_fields(self, data): if not data.get('engine_rtp_icesupport'): return required_field = 'engine_rtp_stunaddr' if not data.get(required_field): raise ValidationError( 'Missing keys for rtp configuration: {}'.format( required_field), field_name=required_field, )
class _UserEmailSchema(BaseSchema): address = fields.Email(required=True) main = fields.Boolean(missing=False)
class StatusSchema(Schema): class Meta: ordered = True unknown = EXCLUDE full = fields.Boolean()
class BaseListSchema(mallow.ListSchema): recurse = fields.Boolean(missing=False)
class RecordingSchema(Schema): uuid = fields.UUID() start_time = fields.DateTime() end_time = fields.DateTime() deleted = fields.Boolean() filename = fields.String()