예제 #1
0
class OutcallSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(validate=Length(max=128), required=True)
    internal_caller_id = StrictBoolean()
    preprocess_subroutine = fields.String(validate=Length(max=39),
                                          allow_none=True)
    ring_time = fields.Integer(validate=Range(min=0), allow_none=True)
    description = fields.String(allow_none=True)
    enabled = StrictBoolean()
    links = ListLink(Link('outcalls'))
    trunks = Nested(
        'TrunkSchema',
        only=['tenant_uuid', 'id', 'endpoint_sip', 'endpoint_custom', 'links'],
        many=True,
        dump_only=True,
    )
    extensions = Nested('DialPatternSchema',
                        attribute='dialpatterns',
                        many=True,
                        dump_only=True)
    schedules = Nested(
        'ScheduleSchema',
        only=['tenant_uuid', 'id', 'name', 'links'],
        many=True,
        dump_only=True,
    )
    call_permissions = Nested(
        'CallPermissionSchema',
        only=['tenant_uuid', 'id', 'name', 'links'],
        many=True,
        dump_only=True,
    )
예제 #2
0
class VoicemailSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(validate=Length(max=80), required=True)
    number = fields.String(validate=Regexp(NUMBER_REGEX), required=True)
    context = fields.String(required=True)
    password = fields.String(validate=Regexp(PASSWORD_REGEX), allow_none=True)
    email = fields.String(validate=Length(max=80), allow_none=True)
    language = fields.String(validate=Regexp(LANGUAGE_REGEX), allow_none=True)
    timezone = fields.String(allow_none=True)
    pager = fields.String(validate=Length(max=80), allow_none=True)
    max_messages = fields.Integer(validate=Range(min=0), allow_none=True)
    attach_audio = StrictBoolean(allow_none=True)
    delete_messages = StrictBoolean()
    ask_password = StrictBoolean()
    enabled = StrictBoolean()
    options = fields.List(
        fields.List(fields.String(), validate=Length(equal=2)))
    links = ListLink(Link('voicemails'))

    users = Nested(
        'UserSchema',
        only=['uuid', 'firstname', 'lastname', 'links'],
        many=True,
        dump_only=True,
    )
예제 #3
0
class TrunkSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    context = fields.String(allow_none=True)
    twilio_incoming = StrictBoolean(allow_none=True)
    links = ListLink(Link('trunks'))

    endpoint_sip = fields.Nested('SipSchema',
                                 only=['id', 'username', 'links'],
                                 dump_only=True)
    endpoint_custom = fields.Nested('CustomSchema',
                                    only=['id', 'interface', 'links'],
                                    dump_only=True)
    endpoint_iax = fields.Nested('IAXSchema',
                                 only=['id', 'name', 'links'],
                                 dump_only=True)
    outcalls = fields.Nested('OutcallSchema',
                             only=['id', 'name', 'links'],
                             many=True,
                             dump_only=True)
    register_iax = fields.Nested('RegisterIAXSchema',
                                 only=['id', 'links'],
                                 dump_only=True)
    register_sip = fields.Nested('RegisterSIPSchema',
                                 only=['id', 'links'],
                                 dump_only=True)
예제 #4
0
class TrunkSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    context = fields.String(allow_none=True)
    twilio_incoming = StrictBoolean(allow_none=True)
    links = ListLink(Link('trunks'))

    endpoint_sip = Nested(
        'EndpointSIPSchema',
        only=[
            'uuid',
            'label',
            'name',
            'auth_section_options.username',
            'registration_section_options.client_uri',
            'links',
        ],
        dump_only=True,
    )
    endpoint_custom = Nested(
        'CustomSchema', only=['id', 'interface', 'links'], dump_only=True
    )
    endpoint_iax = Nested('IAXSchema', only=['id', 'name', 'links'], dump_only=True)
    outcalls = Nested(
        'OutcallSchema', only=['id', 'name', 'links'], many=True, dump_only=True
    )
    register_iax = Nested('RegisterIAXSchema', only=['id', 'links'], dump_only=True)
예제 #5
0
class VoicemailDestinationSchema(BaseDestinationSchema):
    voicemail_id = fields.Integer(attribute='actionarg1', required=True)
    skip_instructions = StrictBoolean()
    greeting = fields.String(validate=OneOf(['busy', 'unavailable']),
                             allow_none=True)

    voicemail = fields.Nested('VoicemailSchema', only=['name'], dump_only=True)

    @pre_dump
    def separate_action(self, data):
        options = data.actionarg2 if data.actionarg2 else ''
        data.skip_instructions = True if 's' in options else False
        data.greeting = ('busy' if 'b' in options else
                         'unavailable' if 'u' in options else None)
        return data

    @post_load
    def merge_action(self, data):
        greeting = data.pop('greeting', None)
        data['actionarg2'] = '{}{}'.format(
            'b' if greeting == 'busy' else
            'u' if greeting == 'unavailable' else '',
            's' if data.pop('skip_instructions', False) else '',
        )
        return data

    @post_dump
    def make_voicemail_fields_flat(self, data):
        if data.get('voicemail'):
            data['voicemail_name'] = data['voicemail']['name']

        data.pop('voicemail', None)
        return data
예제 #6
0
class CallPermissionSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(validate=Length(min=1, max=128), required=True)
    password = fields.String(validate=Regexp(PASSWORD_REGEX), allow_none=True)
    mode = fields.String(validate=OneOf(['allow', 'deny']))
    extensions = fields.List(fields.String(validate=Regexp(EXTENSION_REGEX)))
    enabled = StrictBoolean()
    description = fields.String(allow_none=True)
    links = ListLink(Link('callpermissions'))

    outcalls = Nested('OutcallSchema',
                      only=['id', 'name', 'links'],
                      many=True,
                      dump_only=True)
    groups = Nested('GroupSchema',
                    only=['uuid', 'id', 'name', 'links'],
                    many=True,
                    dump_only=True)
    users = Nested(
        'UserSchema',
        only=['uuid', 'firstname', 'lastname', 'links'],
        many=True,
        dump_only=True,
    )
예제 #7
0
class ForwardUnconditionalSchema(BaseSchema):
    enabled = StrictBoolean(attribute='unconditional_enabled')
    destination = fields.String(attribute='unconditional_destination',
                                validate=Length(max=128),
                                allow_none=True)

    types = ['unconditional']
예제 #8
0
class ForwardNoAnswerSchema(BaseSchema):
    enabled = StrictBoolean(attribute='noanswer_enabled')
    destination = fields.String(attribute='noanswer_destination',
                                validate=Length(max=128),
                                allow_none=True)

    types = ['noanswer']
예제 #9
0
class ForwardBusySchema(BaseSchema):
    enabled = StrictBoolean(attribute='busy_enabled')
    destination = fields.String(attribute='busy_destination',
                                validate=Length(max=128),
                                allow_none=True)

    types = ['busy']
예제 #10
0
class CustomSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    interface = fields.String(validate=Regexp(INTERFACE_REGEX), required=True)
    interface_suffix = fields.String(validate=Length(max=32), allow_none=True)
    enabled = StrictBoolean()
    links = ListLink(Link('endpoint_custom'))

    trunk = Nested('TrunkSchema', only=['id', 'links'], dump_only=True)
    line = Nested('LineSchema', only=['id', 'links'], dump_only=True)
예제 #11
0
class WizardSchema(BaseSchema):
    xivo_uuid = fields.UUID(dump_only=True)
    admin_username = fields.Constant(constant='root', dump_only=True)
    admin_password = fields.String(validate=Regexp(ADMIN_PASSWORD_REGEX),
                                   required=True)
    license = StrictBoolean(validate=Equal(True), required=True)
    language = fields.String(validate=OneOf(['en_US', 'fr_FR']),
                             missing='en_US')
    timezone = fields.String(validate=Length(max=128), required=True)
    network = Nested(WizardNetworkSchema, required=True)
    steps = Nested(WizardStepsSchema, missing=WizardStepsSchema().load({}))
예제 #12
0
class UserSummarySchema(BaseSchema):
    id = fields.Integer()
    uuid = fields.String()
    firstname = fields.String()
    lastname = fields.String()
    email = fields.String()
    extension = fields.String()
    context = fields.String()
    provisioning_code = fields.String()
    protocol = fields.String()
    enabled = StrictBoolean()
예제 #13
0
class ContextSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    name = fields.String(
        validate=(
            Regexp(CONTEXT_REGEX),
            Length(min=1, max=39),
            NoneOf(
                [
                    'authentication',
                    'general',
                    'global',
                    'globals',
                    'parkedcalls',
                    'xivo-features',
                    'zonemessages',
                ]
            ),
        ),
        required=True,
    )
    label = fields.String(validate=Length(max=128), allow_none=True)
    type = fields.String(
        validate=OneOf(['internal', 'incall', 'outcall', 'services', 'others'])
    )
    user_ranges = Nested(RangeSchema, many=True)
    group_ranges = Nested(RangeSchema, many=True)
    queue_ranges = Nested(RangeSchema, many=True)
    conference_room_ranges = Nested(RangeSchema, many=True)
    incall_ranges = Nested(IncallRangeSchema, many=True)
    description = fields.String(allow_none=True)
    tenant_uuid = fields.String(dump_only=True)
    enabled = StrictBoolean()
    links = ListLink(Link('contexts'))

    contexts = Nested(
        'ContextSchema',
        only=['id', 'name', 'label', 'links'],
        many=True,
        dump_only=True,
    )

    @post_load
    def create_objects(self, data, **kwargs):
        for key in [
            'user_ranges',
            'group_ranges',
            'queue_ranges',
            'conference_room_ranges',
            'incall_ranges',
        ]:
            if data.get(key):
                data[key] = [ContextNumbers(**d) for d in data[key]]
        return data
예제 #14
0
class SoundDestinationSchema(BaseDestinationSchema):
    filename = fields.String(validate=Length(max=255),
                             attribute='actionarg1',
                             required=True)
    skip = StrictBoolean()
    no_answer = StrictBoolean()

    @pre_dump
    def separate_action(self, data):
        options = data.actionarg2 if data.actionarg2 else ''
        data.skip = True if 'skip' in options else False
        data.no_answer = True if 'noanswer' in options else False
        return data

    @post_load
    def merge_action(self, data):
        data['actionarg2'] = '{skip}{noanswer}'.format(
            skip='skip' if data.pop('skip', False) else '',
            noanswer='noanswer' if data.pop('no_answer', False) else '',
        )
        return data
예제 #15
0
class DeviceSchema(BaseSchema):
    id = fields.String(dump_only=True)
    status = fields.String(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    is_new = StrictBoolean(dump_only=True)
    ip = fields.String(validate=Regexp(IP_REGEX), allow_none=True)
    mac = fields.String(validate=Regexp(MAC_REGEX), allow_none=True)
    sn = fields.String(allow_none=True)
    plugin = fields.String(allow_none=True)
    vendor = fields.String(allow_none=True)
    model = fields.String(allow_none=True)
    version = fields.String(allow_none=True)
    description = fields.String(allow_none=True)
    template_id = fields.String(allow_none=True)
    options = Nested(DeviceOptionsSchema, allow_none=True)
    links = ListLink(Link('devices'))
예제 #16
0
class CallFilterSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(validate=Length(max=128), required=True)
    strategy = fields.String(
        validate=OneOf([
            'all-recipients-then-linear-surrogates',
            'all-recipients-then-all-surrogates',
            'all-surrogates-then-all-recipients',
            'linear-surrogates-then-all-recipients',
            'all',
        ]),
        required=True,
    )
    source = fields.String(
        validate=OneOf(['internal', 'external', 'all']),
        attribute='callfrom',
        required=True,
    )
    caller_id_mode = fields.String(validate=OneOf(
        ['prepend', 'overwrite', 'append']),
                                   allow_none=True)
    caller_id_name = fields.String(validate=Length(max=80), allow_none=True)
    surrogates_timeout = fields.Integer(validate=Range(min=0), allow_none=True)
    description = fields.String(allow_none=True)
    enabled = StrictBoolean()
    links = ListLink(Link('callfilters'))

    recipients = fields.Nested('CallFilterRecipientsSchema',
                               many=True,
                               dump_only=True)
    surrogates = fields.Nested('CallFilterSurrogatesSchema',
                               many=True,
                               dump_only=True)
    fallbacks = fields.Nested('CallFilterFallbackSchema', dump_only=True)

    @post_dump
    def wrap_users(self, data):
        recipient_users = data.pop('recipients', [])
        surrogate_users = data.pop('surrogates', [])

        if not self.only or 'recipients' in self.only:
            data['recipients'] = {'users': recipient_users}
        if not self.only or 'surrogates' in self.only:
            data['surrogates'] = {'users': surrogate_users}

        return data
예제 #17
0
class CallPickupSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(validate=Length(max=128), required=True)
    description = fields.String(allow_none=True)
    enabled = StrictBoolean()
    links = ListLink(Link('callpickups'))

    group_interceptors = Nested('GroupSchema',
                                only=['id', 'name'],
                                many=True,
                                dump_only=True)
    group_targets = Nested('GroupSchema',
                           only=['id', 'name'],
                           many=True,
                           dump_only=True)
    user_interceptors = Nested('UserSchema',
                               only=['uuid', 'firstname', 'lastname'],
                               many=True,
                               dump_only=True)
    user_targets = Nested('UserSchema',
                          only=['uuid', 'firstname', 'lastname'],
                          many=True,
                          dump_only=True)

    @post_dump
    def wrap_users(self, data, **kwargs):
        interceptor_groups = data.pop('group_interceptors', [])
        interceptor_users = data.pop('user_interceptors', [])
        target_groups = data.pop('group_targets', [])
        target_users = data.pop('user_targets', [])

        if not self.only or 'interceptors' in self.only:
            data['interceptors'] = {
                'groups': interceptor_groups,
                'users': interceptor_users,
            }
        if not self.only or 'targets' in self.only:
            data['targets'] = {'groups': target_groups, 'users': target_users}

        return data
예제 #18
0
class GroupSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    uuid = fields.String(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(dump_only=True)
    label = fields.String(validate=[Length(max=128),
                                    Regexp(LABEL_REGEX)],
                          required=True)
    preprocess_subroutine = fields.String(validate=Length(max=39),
                                          allow_none=True)
    ring_strategy = fields.String(validate=OneOf([
        'all',
        'random',
        'least_recent',
        'linear',  # Issue when editing to this value: ASTERISK-17049
        'fewest_calls',
        'memorized_round_robin',
        'weight_random',
    ]))
    caller_id_mode = fields.String(validate=OneOf(
        ['prepend', 'overwrite', 'append']),
                                   allow_none=True)
    caller_id_name = fields.String(validate=Length(max=80), allow_none=True)
    timeout = fields.Integer(validate=Range(min=0), allow_none=True)
    user_timeout = fields.Integer(validate=Range(min=0), allow_none=True)
    retry_delay = fields.Integer(validate=Range(min=0), allow_none=True)
    music_on_hold = fields.String(validate=Length(max=128), allow_none=True)
    ring_in_use = StrictBoolean()
    mark_answered_elsewhere = StrictBoolean(
        attribute='mark_answered_elsewhere_bool')
    enabled = StrictBoolean()
    links = ListLink(Link('groups', field='uuid'))

    extensions = Nested(
        'ExtensionSchema',
        only=['id', 'exten', 'context', 'links'],
        many=True,
        dump_only=True,
    )
    fallbacks = Nested('GroupFallbackSchema', dump_only=True)
    incalls = Nested('IncallSchema',
                     only=['id', 'extensions', 'links'],
                     many=True,
                     dump_only=True)
    user_queue_members = Nested('GroupUsersMemberSchema',
                                many=True,
                                dump_only=True)
    extension_queue_members = Nested('GroupExtensionsMemberSchema',
                                     many=True,
                                     dump_only=True)
    schedules = Nested('ScheduleSchema',
                       only=['id', 'name', 'links'],
                       many=True,
                       dump_only=True)
    call_permissions = Nested('CallPermissionSchema',
                              only=['id', 'name', 'links'],
                              many=True,
                              dump_only=True)

    # DEPRECATED 21.04
    @pre_load
    def copy_name_to_label(self, data, **kwargs):
        if 'label' in data:
            return data
        if 'name' in data:
            logger.warning(
                'the "name" field of groups is deprecated. use "label" instead'
            )
            data['label'] = data['name']
        return data

    @post_dump
    def convert_ring_strategy_to_user(self, data, **kwargs):
        ring_strategy = data.get('ring_strategy', None)
        if ring_strategy == 'ringall':
            data['ring_strategy'] = 'all'
        elif ring_strategy == 'leastrecent':
            data['ring_strategy'] = 'least_recent'
        elif ring_strategy == 'fewestcalls':
            data['ring_strategy'] = 'fewest_calls'
        elif ring_strategy == 'rrmemory':
            data['ring_strategy'] = 'memorized_round_robin'
        elif ring_strategy == 'wrandom':
            data['ring_strategy'] = 'weight_random'
        return data

    @post_dump
    def wrap_users_member(self, data, **kwargs):
        users_member = data.pop('user_queue_members', [])
        extensions_member = data.pop('extension_queue_members', [])
        if not self.only or 'members' in self.only:
            data['members'] = {
                'users': users_member,
                'extensions': extensions_member
            }
        return data

    @post_load
    def convert_ring_strategy_to_database(self, data, **kwargs):
        ring_strategy = data.get('ring_strategy', None)
        if ring_strategy == 'all':
            data['ring_strategy'] = 'ringall'
        elif ring_strategy == 'least_recent':
            data['ring_strategy'] = 'leastrecent'
        elif ring_strategy == 'fewest_calls':
            data['ring_strategy'] = 'fewestcalls'
        elif ring_strategy == 'memorized_round_robin':
            data['ring_strategy'] = 'rrmemory'
        elif ring_strategy == 'weight_random':
            data['ring_strategy'] = 'wrandom'
        return data
예제 #19
0
class GroupSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(
        validate=(Regexp(NAME_REGEX), NoneOf(['general']), Length(max=128)),
        required=True,
    )
    preprocess_subroutine = fields.String(validate=Length(max=39),
                                          allow_none=True)
    ring_strategy = fields.String(validate=OneOf([
        'all',
        'random',
        'least_recent',
        'linear',  # Issue when editing to this value: ASTERISK-17049
        'fewest_calls',
        'memorized_round_robin',
        'weight_random',
    ]))
    caller_id_mode = fields.String(validate=OneOf(
        ['prepend', 'overwrite', 'append']),
                                   allow_none=True)
    caller_id_name = fields.String(validate=Length(max=80), allow_none=True)
    timeout = fields.Integer(validate=Range(min=0), allow_none=True)
    user_timeout = fields.Integer(validate=Range(min=0), allow_none=True)
    retry_delay = fields.Integer(validate=Range(min=0), allow_none=True)
    music_on_hold = fields.String(validate=Length(max=128), allow_none=True)
    ring_in_use = StrictBoolean()
    enabled = StrictBoolean()
    links = ListLink(Link('groups'))

    extensions = fields.Nested(
        'ExtensionSchema',
        only=['id', 'exten', 'context', 'links'],
        many=True,
        dump_only=True,
    )
    fallbacks = fields.Nested('GroupFallbackSchema', dump_only=True)
    incalls = fields.Nested('IncallSchema',
                            only=['id', 'extensions', 'links'],
                            many=True,
                            dump_only=True)
    user_queue_members = fields.Nested('GroupUsersMemberSchema',
                                       many=True,
                                       dump_only=True)
    extension_queue_members = fields.Nested('GroupExtensionsMemberSchema',
                                            many=True,
                                            dump_only=True)
    schedules = fields.Nested('ScheduleSchema',
                              only=['id', 'name', 'links'],
                              many=True,
                              dump_only=True)
    call_permissions = fields.Nested('CallPermissionSchema',
                                     only=['id', 'name', 'links'],
                                     many=True,
                                     dump_only=True)

    @post_dump
    def convert_ring_strategy_to_user(self, data):
        ring_strategy = data.get('ring_strategy', None)
        if ring_strategy == 'ringall':
            data['ring_strategy'] = 'all'
        elif ring_strategy == 'leastrecent':
            data['ring_strategy'] = 'least_recent'
        elif ring_strategy == 'fewestcalls':
            data['ring_strategy'] = 'fewest_calls'
        elif ring_strategy == 'rrmemory':
            data['ring_strategy'] = 'memorized_round_robin'
        elif ring_strategy == 'wrandom':
            data['ring_strategy'] = 'weight_random'
        return data

    @post_dump
    def wrap_users_member(self, data):
        users_member = data.pop('user_queue_members', [])
        extensions_member = data.pop('extension_queue_members', [])
        if not self.only or 'members' in self.only:
            data['members'] = {
                'users': users_member,
                'extensions': extensions_member
            }
        return data

    @post_load
    def convert_ring_strategy_to_database(self, data):
        ring_strategy = data.get('ring_strategy', None)
        if ring_strategy == 'all':
            data['ring_strategy'] = 'ringall'
        elif ring_strategy == 'least_recent':
            data['ring_strategy'] = 'leastrecent'
        elif ring_strategy == 'fewest_calls':
            data['ring_strategy'] = 'fewestcalls'
        elif ring_strategy == 'memorized_round_robin':
            data['ring_strategy'] = 'rrmemory'
        elif ring_strategy == 'weight_random':
            data['ring_strategy'] = 'wrandom'
        return data
예제 #20
0
class ServiceIncallFilterSchema(BaseSchema):
    enabled = StrictBoolean(attribute='incallfilter_enabled', required=True)

    types = ['incallfilter']
예제 #21
0
class ServiceDNDSchema(BaseSchema):
    enabled = StrictBoolean(attribute='dnd_enabled', required=True)

    types = ['dnd']
예제 #22
0
class UserSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    uuid = fields.String(dump_only=True)
    firstname = fields.String(validate=Length(max=128), required=True)
    lastname = fields.String(validate=Length(max=128), allow_none=True)
    email = fields.Email(validate=Length(max=254), allow_none=True)
    timezone = fields.String(validate=Length(max=128), allow_none=True)
    language = fields.String(validate=Regexp(LANGUAGE_REGEX), allow_none=True)
    description = fields.String(allow_none=True)
    caller_id = fields.String(validate=(Regexp(CALLER_ID_REGEX),
                                        Length(max=160)))
    outgoing_caller_id = fields.String(validate=Length(max=80),
                                       allow_none=True)
    mobile_phone_number = fields.String(
        validate=(Regexp(MOBILE_PHONE_NUMBER_REGEX), Length(max=80)),
        allow_none=True)
    username = fields.String(validate=Regexp(USERNAME_REGEX), allow_none=True)
    password = fields.String(validate=Regexp(PASSWORD_REGEX), allow_none=True)
    music_on_hold = fields.String(validate=Length(max=128), allow_none=True)
    preprocess_subroutine = fields.String(validate=Length(max=39),
                                          allow_none=True)
    userfield = fields.String(validate=Length(max=128), allow_none=True)
    call_transfer_enabled = StrictBoolean()
    dtmf_hangup_enabled = StrictBoolean()
    call_record_enabled = StrictBoolean()
    call_record_outgoing_external_enabled = StrictBoolean()
    call_record_outgoing_internal_enabled = StrictBoolean()
    call_record_incoming_internal_enabled = StrictBoolean()
    call_record_incoming_external_enabled = StrictBoolean()
    online_call_record_enabled = StrictBoolean()
    supervision_enabled = StrictBoolean()
    ring_seconds = fields.Integer(validate=Range(min=0, max=10800))
    simultaneous_calls = fields.Integer(validate=Range(min=1, max=20))
    call_permission_password = fields.String(
        validate=Regexp(CALL_PERMISSION_PASSWORD_REGEX), allow_none=True)
    subscription_type = fields.Integer(validate=Range(min=0, max=10))
    created_at = fields.DateTime(dump_only=True)
    enabled = StrictBoolean()
    tenant_uuid = fields.String(dump_only=True)
    links = ListLink(Link('users'))

    agent = Nested('AgentSchema',
                   only=['id', 'number', 'links'],
                   dump_only=True)
    call_permissions = Nested('CallPermissionSchema',
                              only=['id', 'name', 'links'],
                              many=True,
                              dump_only=True)
    call_pickup_user_targets_flat = Nested(
        'UserSchema',
        only=['uuid', 'firstname', 'lastname', 'links'],
        many=True,
        dump_only=True,
    )

    fallbacks = Nested('UserFallbackSchema', dump_only=True)
    groups = Nested('GroupSchema',
                    only=['uuid', 'id', 'name', 'links'],
                    many=True,
                    dump_only=True)
    incalls = Nested('IncallSchema',
                     only=['id', 'extensions', 'links'],
                     many=True,
                     dump_only=True)
    lines = Nested(
        'LineSchema',
        only=[
            'id',
            'name',
            'endpoint_sip',
            'endpoint_sccp',
            'endpoint_custom',
            'extensions',
            'links',
        ],
        many=True,
        dump_only=True,
    )
    forwards = Nested('ForwardsSchema', dump_only=True)
    schedules = Nested('ScheduleSchema',
                       only=['id', 'name', 'links'],
                       many=True,
                       dump_only=True)
    services = Nested('ServicesSchema', dump_only=True)
    switchboards = Nested('SwitchboardSchema',
                          only=['uuid', 'name', 'links'],
                          many=True,
                          dump_only=True)
    voicemail = Nested('VoicemailSchema',
                       only=['id', 'name', 'links'],
                       dump_only=True)
    queues = Nested('QueueSchema',
                    only=['id', 'name', 'label', 'links'],
                    many=True,
                    dump_only=True)

    @pre_dump
    def flatten_call_pickup_targets(self, data, **kwargs):
        if self.only and 'call_pickup_target_users' not in self.only:
            return data

        all_ = [
            list(data.users_from_call_pickup_group_interceptors_user_targets),
            list(data.users_from_call_pickup_group_interceptors_group_targets),
            list(data.users_from_call_pickup_user_targets),
            list(data.users_from_call_pickup_group_targets),
        ]
        data.call_pickup_user_targets_flat = list(set(self._flatten(all_)))

        return data

    @post_dump
    def format_call_pickup_targets(self, data, **kwargs):
        if not self.only or 'call_pickup_target_users' in self.only:
            call_pickup_user_targets = data.pop(
                'call_pickup_user_targets_flat', [])
            data['call_pickup_target_users'] = call_pickup_user_targets
        return data

    @classmethod
    def _flatten(cls, iterable_of_iterable):
        for item in iterable_of_iterable:
            try:
                itercheck = iter(item)
                yield from cls._flatten(itercheck)
            except TypeError:
                yield item

    # DEPRECATED 20.01
    @validates_schema
    def validate_schema(self, data, **kwargs):
        call_record_any_enabled = any((
            data.get('call_record_outgoing_external_enabled') is not None,
            data.get('call_record_outgoing_internal_enabled') is not None,
            data.get('call_record_incoming_external_enabled') is not None,
            data.get('call_record_incoming_internal_enabled') is not None,
        ))
        deprecated_call_record_enabled = data.get(
            'call_record_enabled') is not None
        if deprecated_call_record_enabled and call_record_any_enabled:
            raise ValidationError(
                "'call_record_enabled' is deprecated and incompatible with 'call_record_*_enabled' options"
            )

    # DEPRECATED 20.01
    @post_dump
    def dump_call_record_enable_deprecated(self, data, **kwargs):
        if self.only and 'call_record_enabled' not in self.only:
            return data

        call_record_all_enabled = all((
            data.get('call_record_outgoing_external_enabled'),
            data.get('call_record_outgoing_internal_enabled'),
            data.get('call_record_incoming_external_enabled'),
            data.get('call_record_incoming_internal_enabled'),
        ))
        data['call_record_enabled'] = call_record_all_enabled
        return data

    # DEPRECATED 20.01
    @post_load
    def load_call_record_enable_deprecated(self, data, **kwargs):
        call_record_enabled = data.pop('call_record_enabled', None)
        if call_record_enabled is None:
            return data

        if call_record_enabled:
            data['call_record_outgoing_external_enabled'] = True
            data['call_record_outgoing_internal_enabled'] = True
            data['call_record_incoming_external_enabled'] = True
            data['call_record_incoming_internal_enabled'] = True
        else:
            data['call_record_outgoing_external_enabled'] = False
            data['call_record_outgoing_internal_enabled'] = False
            data['call_record_incoming_external_enabled'] = False
            data['call_record_incoming_internal_enabled'] = False
        return data
예제 #23
0
class UserSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    uuid = fields.String(dump_only=True)
    firstname = fields.String(validate=Length(max=128), required=True)
    lastname = fields.String(validate=Length(max=128), allow_none=True)
    email = fields.Email(validate=Length(max=254), allow_none=True)
    timezone = fields.String(validate=Length(max=128), allow_none=True)
    language = fields.String(validate=Regexp(LANGUAGE_REGEX), allow_none=True)
    description = fields.String(allow_none=True)
    caller_id = fields.String(validate=(Regexp(CALLER_ID_REGEX),
                                        Length(max=160)))
    outgoing_caller_id = fields.String(validate=Length(max=80),
                                       allow_none=True)
    mobile_phone_number = fields.String(
        validate=(Regexp(MOBILE_PHONE_NUMBER_REGEX), Length(max=80)),
        allow_none=True)
    username = fields.String(validate=Regexp(USERNAME_REGEX), allow_none=True)
    password = fields.String(validate=Regexp(PASSWORD_REGEX), allow_none=True)
    music_on_hold = fields.String(validate=Length(max=128), allow_none=True)
    preprocess_subroutine = fields.String(validate=Length(max=39),
                                          allow_none=True)
    userfield = fields.String(validate=Length(max=128), allow_none=True)
    call_transfer_enabled = StrictBoolean()
    dtmf_hangup_enabled = StrictBoolean()
    call_record_enabled = StrictBoolean()
    online_call_record_enabled = StrictBoolean()
    supervision_enabled = StrictBoolean()
    ring_seconds = fields.Integer(validate=Range(min=0, max=60))
    simultaneous_calls = fields.Integer(validate=Range(min=1, max=20))
    call_permission_password = fields.String(
        validate=Regexp(CALL_PERMISSION_PASSWORD_REGEX), allow_none=True)
    subscription_type = fields.Integer(validate=Range(min=0, max=10))
    created_at = fields.DateTime(dump_only=True)
    enabled = StrictBoolean()
    tenant_uuid = fields.String(dump_only=True)
    links = ListLink(Link('users'))

    agent = fields.Nested('AgentSchema',
                          only=['id', 'number', 'links'],
                          dump_only=True)
    call_permissions = fields.Nested('CallPermissionSchema',
                                     only=['id', 'name', 'links'],
                                     many=True,
                                     dump_only=True)
    fallbacks = fields.Nested('UserFallbackSchema', dump_only=True)
    groups = fields.Nested('GroupSchema',
                           only=['id', 'name', 'links'],
                           many=True,
                           dump_only=True)
    incalls = fields.Nested('IncallSchema',
                            only=['id', 'extensions', 'links'],
                            many=True,
                            dump_only=True)
    lines = fields.Nested(
        'LineSchema',
        only=[
            'id',
            'name',
            'endpoint_sip',
            'endpoint_sccp',
            'endpoint_custom',
            'extensions',
            'links',
        ],
        many=True,
        dump_only=True,
    )
    forwards = fields.Nested('ForwardsSchema', dump_only=True)
    schedules = fields.Nested('ScheduleSchema',
                              only=['id', 'name', 'links'],
                              many=True,
                              dump_only=True)
    services = fields.Nested('ServicesSchema', dump_only=True)
    switchboards = fields.Nested('SwitchboardSchema',
                                 only=['uuid', 'name', 'links'],
                                 many=True,
                                 dump_only=True)
    voicemail = fields.Nested('VoicemailSchema',
                              only=['id', 'name', 'links'],
                              dump_only=True)
    queues = fields.Nested('QueueSchema',
                           only=['id', 'name', 'label', 'links'],
                           many=True,
                           dump_only=True)
예제 #24
0
class FuncKeySchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    inherited = fields.Boolean(dump_only=True)
    blf = StrictBoolean()
    label = fields.String(allow_none=True)
    destination = FuncKeyDestinationField(BaseDestinationSchema, required=True)
예제 #25
0
class QueueSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(
        validate=(Regexp(NAME_REGEX), NoneOf(['general']), Length(max=128)),
        required=True,
    )
    label = fields.String(validate=Length(max=128), missing=None)
    data_quality = StrictBoolean(attribute='data_quality_bool')
    dtmf_hangup_callee_enabled = StrictBoolean()
    dtmf_hangup_caller_enabled = StrictBoolean()
    dtmf_transfer_callee_enabled = StrictBoolean()
    dtmf_transfer_caller_enabled = StrictBoolean()
    dtmf_record_callee_enabled = StrictBoolean()
    dtmf_record_caller_enabled = StrictBoolean()
    retry_on_timeout = StrictBoolean()
    ring_on_hold = StrictBoolean()
    timeout = fields.Integer(validate=Range(min=0), allow_none=True)
    announce_hold_time_on_entry = StrictBoolean()
    ignore_forward = StrictBoolean(attribute='ignore_forward_bool')
    preprocess_subroutine = fields.String(validate=Length(max=39),
                                          allow_none=True)
    music_on_hold = fields.String(validate=Length(max=128), allow_none=True)
    wait_time_threshold = fields.Integer(validate=Range(min=0),
                                         allow_none=True)
    wait_time_destination = DestinationField(allow_none=True)
    wait_ratio_threshold = fields.Float(validate=Range(min=0), allow_none=True)
    wait_ratio_destination = DestinationField(allow_none=True)
    caller_id_mode = fields.String(validate=OneOf(
        ['prepend', 'overwrite', 'append']),
                                   allow_none=True)
    caller_id_name = fields.String(validate=Length(max=80), allow_none=True)
    enabled = StrictBoolean()
    options = fields.List(
        fields.List(fields.String(), validate=Length(equal=2)))
    links = ListLink(Link('queues'))

    extensions = fields.Nested(
        'ExtensionSchema',
        only=['id', 'exten', 'context', 'links'],
        many=True,
        dump_only=True,
    )
    schedules = fields.Nested('ScheduleSchema',
                              only=['id', 'name', 'links'],
                              many=True,
                              dump_only=True)
    agent_queue_members = fields.Nested('QueueAgentQueueMembersSchema',
                                        many=True,
                                        dump_only=True)
    user_queue_members = fields.Nested('QueueUserQueueMembersSchema',
                                       many=True,
                                       dump_only=True)

    @post_load
    def create_objects(self, data):
        for key in ('wait_time_destination', 'wait_ratio_destination'):
            if data.get(key):
                data[key] = Dialaction(**data[key])
        return data

    @post_dump
    def wrap_members(self, data):
        if not self.only or 'members' in self.only:
            data['members'] = {
                'agents': data.pop('agent_queue_members', []),
                'users': data.pop('user_queue_members', []),
            }
        return data
예제 #26
0
class LiveReloadSchema(BaseSchema):
    enabled = StrictBoolean(required=True)
예제 #27
0
class DeviceOptionsSchema(BaseSchema):
    switchboard = StrictBoolean()
예제 #28
0
class RegisterIAXSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    auth_username = fields.String(validate=Regexp(INVALID_CHAR),
                                  allow_none=True)
    auth_password = fields.String(validate=Regexp(INVALID_CHAR),
                                  allow_none=True)
    remote_host = fields.String(validate=Regexp(INVALID_REMOTE_HOST),
                                required=True)
    remote_port = fields.Integer(validate=Range(min=0, max=65535),
                                 allow_none=True)
    callback_extension = fields.String(
        validate=Regexp(INVALID_CALLBACK_EXTENSION), allow_none=True)
    callback_context = fields.String(allow_none=True)
    enabled = StrictBoolean(missing=True)
    links = ListLink(Link('register_iax'))

    trunk = fields.Nested('TrunkSchema', only=['id', 'links'], dump_only=True)

    @validates_schema
    def validate_auth_username(self, data):
        if data.get('auth_username') and not data.get('auth_password'):
            raise ValidationError(
                'Cannot set field "auth_username" if the field "auth_password" is not set',
                'auth_username',
            )

    @validates_schema
    def validate_callback_context(self, data):
        if data.get('callback_context') and not data.get('callback_extension'):
            raise ValidationError(
                'Cannot set field "callback_context" if the field "callback_extension" is not set',
                'callback_context',
            )

    @validates_schema
    def validate_total_length(self, data):
        if len(self.convert_to_chaniax(data)['var_val']) > 255:
            raise ValidationError(
                'The sum of all fields is longer than maximum length 255')

    @post_load
    def convert_to_chaniax(self, data):
        chaniax_fmt = (
            '{auth_username}{auth_password}{separator}'
            '{remote_host}{remote_port}{callback_extension}{callback_context}')
        data['var_val'] = chaniax_fmt.format(
            auth_username=data.get('auth_username')
            if data.get('auth_username') else '',
            auth_password='******'.format(data.get('auth_password'))
            if data.get('auth_password') else '',
            separator='@'
            if data.get('auth_username') or data.get('auth_password') else '',
            remote_host=data.get('remote_host'),
            remote_port=':{}'.format(data.get('remote_port'))
            if data.get('remote_port') else '',
            callback_extension='/{}'.format(data.get('callback_extension'))
            if data.get('callback_extension') else '',
            callback_context='?{}'.format(data.get('callback_context'))
            if data.get('callback_context') else '',
        )
        return data

    @pre_dump
    def convert_from_chaniax(self, data):
        register = REGISTER_REGEX.match(data.var_val)
        result = register.groupdict()
        result['id'] = data.id
        result['enabled'] = data.enabled
        result['trunk'] = data.trunk
        return result