Ejemplo n.º 1
0
    def lookup_row(self, request, node, value):
        if isinstance(node.typ, Sequence):
            row = []
            value_length = len(value)

            for i in range(self.sequence_count[node.name]):
                if i >= value_length:
                    child_value = None
                else:
                    child_value = value[i]

                for child in node.children[0].children:
                    if child_value is None:
                        row.extend(self.lookup_row(request, child, None))
                    elif isinstance(value, dict):
                        row.extend(self.lookup_row(request, child, child_value.get(camelcase(node.name))))
                    else:
                        row.extend(self.lookup_row(request, child, getattr(child_value, child.name, None)))

            return row

        elif isinstance(node.typ, Mapping):
            row = []
            for child in node.children:
                if isinstance(value, dict):
                    row.extend(self.lookup_row(request, child, value.get(camelcase(node.name))))
                else:
                    row.extend(self.lookup_row(request, child, getattr(value, child.name, None)))
            return row

        else:
            if value is not None and hasattr(node, 'value_decoder'):
                value = node.value_decoder(request, value)

            return [value]
Ejemplo n.º 2
0
 def get_route_info(self, request, route_name):
     intr_route = request.registry.introspector.get("routes", route_name)
     if intr_route is not None:
         route = intr_route["object"]
         params = dict((k, "{{%s}}" % camelcase(k)) for k in lookup_for_route_params(route))
         url = "%s%s" % (request.application_url, unquote(route.generate(params)))
         return intr_route, url, params.keys()
Ejemplo n.º 3
0
 def get_route_info(self, request, route_name):
     intr_route = request.registry.introspector.get('routes', route_name)
     if intr_route is not None:
         route = intr_route['object']
         params = {k: '{{%s}}' % camelcase(k) for k in lookup_for_route_params(route)}
         url = '%s%s' % (request.application_url, unquote(route.generate(params)))
         return intr_route, url, params.keys()
Ejemplo n.º 4
0
def format_error_to_json_values(error, kwargs=None, request=None):
    if request:
        translate = translate_factory(request)
    else:
        translate = lambda tstring, **kw: tstring

    if isinstance(error, HTTPError):
        status = error.code
        key = camelcase(error.title)
        title = error.title
        message = error.explanation
    elif isinstance(error, Invalid):
        status = 400
        key = camelcase(error._keyname())
        title = _('Form error')
        message = error.msg

        errors = defaultdict(list)
        for path in error.paths():
            for exc in path:
                key = str(exc.node.name)
                if exc.positional and exc.pos:  # Ignore 0 position
                    key += '.' + str(exc.pos)

                if key and exc.msg:
                    key = camelcase(key)
                    for message in exc.messages():
                        errors[key].append(translate(message))

        if not kwargs:
            kwargs = {}
        kwargs['errors'] = errors
    else:
        status = getattr(error, 'code', 400)
        key = camelcase(getattr(error, 'key', 'undefined'))
        title = getattr(error, 'title', None)
        message = getattr(error, 'msg', getattr(error, 'message', 'Undefined'))

    values = {
        'status': status,
        'property': key,
        'title': title and translate(title) or None,
        'message': translate(message)}
    if kwargs:
        values.update(kwargs)
    return values
Ejemplo n.º 5
0
def format_error_to_json_values(error, kwargs=None, request=None):
    if request:
        translate = translate_factory(request)
    else:
        translate = lambda tstring, **kw: tstring

    if isinstance(error, HTTPError):
        status = error.code
        key = camelcase(error.title)
        message = error.explanation
    elif isinstance(error, Invalid):
        status = 400
        key = camelcase(error._keyname())
        message = error.msg

        errors = MissingList()
        for path in error.paths():
            for exc in path:
                key = str(exc.node.name)
                if exc.positional and exc.pos:  # Ignore 0 position
                    key += '.' + str(exc.pos)

                if key and exc.msg:
                    key = camelcase(key)
                    for message in exc.messages():
                        errors[key].append(translate(message))

        if not kwargs:
            kwargs = {}
        kwargs['errors'] = errors
    else:
        status = getattr(error, 'code', 400)
        key = camelcase(getattr(error, 'key', 'undefined'))
        message = getattr(error, 'msg', getattr(error, 'message', u'Undefined'))

    values = {
        'status': status,
        'property': key,
        'message': translate(message)}
    if kwargs:
        values.update(kwargs)
    return values
Ejemplo n.º 6
0
 def encode_key(self, key):
     return camelcase(key)
Ejemplo n.º 7
0
    def __call__(self, context, request):
        requests = []
        folders = MissingList()
        folders_descriptions = {}
        config = request.registry.config

        for schema_view in request.registry.getAllUtilitiesRegisteredFor(ISchemaView):
            # Make route for url
            schema_route = request.registry.introspector.get('routes', schema_view.route_name)
            if schema_route is not None:
                # Schema permission
                headers = set()
                permissions = lookup_for_route_permissions(request.registry, schema_route)
                method_permissions = maybe_list(permissions.get('GET'))
                for method_permission in method_permissions:
                    if method_permission not in (Everyone, NotAuthenticated):
                        headers.add('Authorization: Token {{token}}')
                        break

                request_id = self.new_unique_id()
                requests.append({
                    'id': request_id,
                    'headers': '\n'.join(headers),
                    'url': request.route_url(schema_view.route_name),
                    'preRequestScript': '',
                    'pathVariables': {},
                    'method': u'GET',
                    'data': [],
                    'dataMode': 'params',
                    'version': 2,
                    'tests': '',
                    'currentHelper': 'normal',
                    'helperAttributes': {},
                    'time': self.collection_time,
                    'name': u'Schema: %s' % schema_view.title,
                    'description': schema_view.description or '',
                    'collectionId': self.collection_id,
                    'responses': [],
                    'owner': 0,
                    'synced': False})
                folders[schema_view.title].append(request_id)
                folders_descriptions[schema_view.title] = schema_view.description

            for route_name, request_methods in schema_view.routes_names.items():
                # Make route for url
                intr_route = request.registry.introspector.get('routes', route_name)
                if intr_route is None:
                    continue
                route = intr_route['object']
                permissions = lookup_for_route_permissions(request.registry, intr_route)
                params = dict((k, '{{%s}}' % camelcase(k)) for k in lookup_for_route_params(route))
                url = '%s%s' % (request.application_url, unquote(route.generate(params)))

                schemas_by_methods = MissingList()
                for schema in config.lookup_input_schema(route_name, request_methods):
                    for request_method in maybe_list(schema.request_method) or DEFAULT_METHODS:
                        schemas_by_methods[request_method].append(schema)
                for schema in config.lookup_output_schema(route_name, request_methods):
                    for request_method in maybe_list(schema.request_method) or DEFAULT_METHODS:
                        schemas_by_methods[request_method].append(schema)

                for request_method, schemas in schemas_by_methods.items():
                    title = None
                    description = None
                    schema_data = []
                    tests = []

                    for schema in schemas:
                        if schema.schema_type == 'request':
                            if schema.schema:
                                schema_data.extend(
                                    self.construct_data(request_method, schema.schema))
                            if schema.fields_schema:
                                schema_data.extend(
                                    self.construct_data(request_method, schema.fields_schema))

                        if schema.schema and not title:
                            title = schema.schema.title
                        if schema.schema and not description:
                            description = schema.schema.description

                        variables = getattr(schema.schema, 'postman_environment_variables', None)
                        if variables:
                            for environment_key, response_key in variables.items():
                                environment_key = camelcase(environment_key)
                                response_key = camelcase(response_key)
                                tests.append(
                                    'if (answer.%s){ postman.setEnvironmentVariable("%s", answer.%s); }'
                                    % (response_key, environment_key, response_key))

                    if tests:
                        tests.insert(0, 'var answer = JSON.parse(responseBody);')

                    # Input params
                    method_url = url
                    request_schema_data = []
                    request_method = request_method.upper()
                    if request_method == 'GET':
                        queries = []
                        for url_param in schema_data:
                            if url_param['value']:
                                queries.append(
                                    '%s=%s'
                                    % (quote(url_param['key']), quote(url_param['value'])))
                            else:
                                queries.append(quote(url_param['key']))
                        if queries:
                            method_url = '%s?%s' % (method_url, '&'.join(queries))
                    else:
                        request_schema_data = schema_data

                    # Method permission
                    headers = set()
                    method_permissions = maybe_list(permissions.get(request_method))
                    for method_permission in method_permissions:
                        if method_permission not in (Everyone, NotAuthenticated):
                            headers.add('Authorization: Token {{token}}')
                            break

                    if not title:
                        title = route_name.replace('_', ' ').title()

                    request_id = self.new_unique_id()
                    requests.append({
                        'id': request_id,
                        'headers': '\n'.join(headers),
                        'url': method_url,
                        'preRequestScript': '',
                        'pathVariables': {},
                        'method': request_method,
                        'data': request_schema_data,
                        'dataMode': 'params',
                        'version': 2,
                        'tests': '\n'.join(tests),
                        'currentHelper': 'normal',
                        'helperAttributes': {},
                        'time': self.collection_time,
                        'name': title,
                        'description': description or '',
                        'collectionId': self.collection_id,
                        'responses': [],
                        'owner': 0,
                        'synced': False})
                    folders[schema_view.title].append(request_id)

        response_folders = []
        for key, requests_ids in folders.items():
            response_folders.append({
                'id': self.new_unique_id(),
                'name': key,
                'description': folders_descriptions.get(key) or '',
                'order': requests_ids,
                'collection_name': self.title,
                'collection_id': self.collection_id,
                'collection_owner': '',
                'write': True})

        return {
            'id': self.collection_id,
            'name': self.title,
            'description': self.description or '',
            'timestamp': self.collection_time,
            'synced': False,
            'owner': '',
            'subscribed': False,
            'remoteLink': '',
            'public': False,
            'write': True,
            'order': [],
            'folders': response_folders,
            'requests': requests}
Ejemplo n.º 8
0
 def encode_key(self, key):
     return camelcase(key) if self.auto_camelcase else key
Ejemplo n.º 9
0
    def __call__(self, context, request):
        nodes = MissingDict()
        requested_methods = [key.lower() for key in request.GET.keys()]

        types = MissingList()
        models = MissingList()
        for route_name, request_methods in self.routes_names.items():
            route_methods = []
            for request_method in maybe_list(request_methods
                                             or DEFAULT_METHODS):
                if not requested_methods or request_method.lower(
                ) in requested_methods:
                    route_methods.append(request_method)
            if not route_methods:
                continue

            intr_route = request.registry.introspector.get(
                'routes', route_name)
            if intr_route is None:
                continue
            route = intr_route['object']
            params = dict((k, '{{%s}}' % camelcase(k))
                          for k in lookup_for_route_params(route))
            url = '%s%s' % (request.application_url,
                            unquote(route.generate(params)))

            schemas = request.registry.config.lookup_input_schema(
                route_name, route_methods)
            schemas.extend(
                request.registry.config.lookup_output_schema(
                    route_name, route_methods))
            for schema in schemas:
                fields = []
                if schema.schema:
                    details = self.construct_structure(request, schema.schema,
                                                       schema.schema_type,
                                                       types, models)
                    if isinstance(details, dict):
                        fields.append(details)
                    else:
                        fields.extend(details)

                if schema.schema_type == 'request' and schema.fields_schema:
                    details = self.construct_structure(request,
                                                       schema.fields_schema,
                                                       schema.schema_type,
                                                       types, models)
                    if isinstance(details, dict):
                        fields.append(details)
                    else:
                        fields.extend(details)

                name = camelcase('%s_%s' %
                                 (schema.request_method, schema.route_name))
                nodes[name][schema.schema_type] = fields
                nodes[name]['method'] = schema.request_method.upper()
                nodes[name]['url'] = url

        nodes['fieldTypes'] = lookup_for_common_fields(types,
                                                       ignore_key='fieldType')
        nodes['models'] = lookup_for_common_fields(models, ignore_key='model')
        return nodes
Ejemplo n.º 10
0
    def construct_data(self, request_method, schema, keep_parent_name=None):
        response = []
        if isinstance(schema.typ, Sequence):
            child = schema.children[0]
            response.extend(self.construct_data(
                request_method,
                child,
                keep_parent_name=schema.name))
            return response

        elif isinstance(schema.typ, Tuple):
            for child in schema.children:
                response.extend(
                    self.construct_data(
                        request_method,
                        child,
                        keep_parent_name=schema.name))
            return response

        elif isinstance(schema.typ, Mapping):
            for child in schema.children:
                response.extend(
                    self.construct_data(
                        request_method,
                        child))
            return response

        else:
            if hasattr(schema.typ, 'typ'):
                return self.construct_data(
                    request_method,
                    schema.typ,
                    keep_parent_name=keep_parent_name)

            default = schema.serialize()
            if default is null:
                default = ''
                if schema.missing not in (drop, required, null):
                    default = schema.missing

            if hasattr(schema, 'postman_default'):
                default = schema.postman_default

            if default == '' and schema.missing is required and request_method.upper() == 'POST':
                if not schema.validator:
                    if isinstance(schema.typ, String):
                        default = '%s {{$randomInt}}' % schema.name.replace('_', ' ').title()
                    elif isinstance(schema.typ, Boolean):
                        default = 'true'
                    elif isinstance(schema.typ, Date):
                        default = TODAY_DATE()
                    elif isinstance(schema.typ, DateTime):
                        default = NOW_DATE()
                else:
                    validators = schema.validator
                    if not is_nonstr_iter(validators):
                        validators = [validators]

                    for validator in validators:
                        if isinstance(validator, OneOf):
                            default = validator.choices[0]
                            break

            if default is None:
                default = ''

            response.append({
                'key': camelcase(keep_parent_name or schema.name),
                'value': str(default),
                'type': 'text',
                'enabled': schema.required})
            return response
Ejemplo n.º 11
0
    def construct_structure(self,
                            request,
                            schema,
                            schema_type,
                            types,
                            models,
                            parent_name=None):
        if isinstance(schema.typ, Sequence):
            child = schema.children[0]
            if not schema.name:
                schema = child

            name = camelcase(schema.name)
            details = {
                'model': name,
                'type': 'sequence',
                'title': schema.title,
                'description': schema.description or None
            }
            models[name].append(details)

            # Find and add child
            child_details = self.construct_structure(request,
                                                     child,
                                                     schema_type,
                                                     types,
                                                     models,
                                                     parent_name=schema.name)

            if isinstance(details, dict):
                if isinstance(child.typ, Mapping):
                    details['type'] = 'model'
                    details.update(child_details)
                else:
                    details['fields'] = [child_details]
            else:
                details['fields'] = child_details

            return details

        elif isinstance(schema.typ, Tuple):
            raise NotImplementedError('Tuple type need to be implemented')

        elif isinstance(schema.typ, Mapping):
            fields = []
            for child in schema.children:
                fields.append(
                    self.construct_structure(request,
                                             child,
                                             schema_type,
                                             types,
                                             models,
                                             parent_name=schema.name))

            name = schema.name or parent_name
            if not name:
                return fields

            name = camelcase(name)
            details = {
                'type': 'model',
                'title': schema.title,
                'description': schema.description or None,
                'fields': fields,
                'model': name
            }
            models[name].append(details)
            return details

        else:
            name = camelcase(schema.name)
            details = {
                'fieldType': name,
                'title': schema.title,
                'description': schema.description or None
            }
            types[name].append(details)

            if isinstance(schema.typ, FilterByType):
                for cls in schema.typ.__class__.__mro__[1:]:
                    if cls is not FilterByType:
                        details['type'] = str(cls.__name__).lower()
                        break
                details['filter'] = True
            else:
                details['type'] = get_colander_type_name(schema.typ)

            request_validation = []
            if schema.validator:
                if isinstance(schema.validator, All):
                    validators = schema.validator.validators
                elif not is_nonstr_iter(schema.validator):
                    validators = [schema.validator]

                for validator in validators:
                    if isinstance(validator, OneOfWithDescription):
                        details['options'] = []
                        for choice, description in validator.choices_with_descripton:
                            details['options'].append({
                                'value':
                                choice,
                                'text':
                                request.translate(description)
                            })
                    elif isinstance(validator, OneOf):
                        details['options'] = []
                        for choice in validator.choices:
                            choice_description = force_unicode(choice).replace(
                                u'_', u' ').title()
                            details['options'].append({
                                'value':
                                choice,
                                'text':
                                choice_description
                            })
                    else:
                        if isinstance(validator, Length):
                            validation_option = {}
                            if validator.min is not None:
                                validation_option['min'] = validator.min
                            if validator.max is not None:
                                validation_option['max'] = validator.max
                        else:
                            validation_option = True

                        request_validation.append(
                            (validator, validation_option))

            if hasattr(schema, 'use_when'):
                details['useWhen'] = dict(
                    (camelcase(k), v) for k, v in schema.use_when.items())

            if schema_type == 'request':
                validation = {}
                if schema.required:
                    validation['required'] = True

                if request_validation:
                    for validator, validation_option in request_validation:
                        validation[get_colander_type_name(
                            validator)] = validation_option
                if validation:
                    details['validation'] = validation

                default = schema.missing
            else:
                if schema.missing is drop:
                    details['maybeNotSent'] = True
                default = schema.default

            if (default is not drop and default is not required
                    and default is not null):
                if isinstance(schema.typ, Number):
                    default = schema.typ.num(default)
                elif isinstance(schema.typ, BaseBoolean):
                    default = asbool(default)
                details['default'] = default

            return details
Ejemplo n.º 12
0
def get_colander_type_name(node):
    return camelcase(str(node.__class__.__name__).lower())
Ejemplo n.º 13
0
 def encode_key(self, key):
     return camelcase(key)
Ejemplo n.º 14
0
 def encode_key(self, key):
     return camelcase(key) if self.auto_camelcase else key
Ejemplo n.º 15
0
        def _render(value, system):
            request = system.get('request')
            if request is not None:
                response = request.response
                ct = response.content_type
                if ct == response.default_content_type:
                    response.content_type = 'text/csv'

                output = request.registry.config.lookup_output_schema(
                    request.matched_route.name, request_method=request.method)
                if output:
                    output = output[0]
                    node = output.schema.children[0]
                    value_lines = []

                    header = []
                    value_lines.append(header)
                    for child in node.children:
                        header.append(child.title)

                    for item_value in value:
                        row = []
                        value_lines.append(row)

                        if isinstance(item_value, dict):
                            for child in node.children:
                                row.append(
                                    item_value.get(camelcase(child.name)))
                        else:
                            for child in node.children:
                                row.append(
                                    getattr(item_value, child.name, None))

                    value = value_lines

            separator = u';'
            separator_replace = u','
            line_break = u'\n'
            line_break_replace = u' '

            lines = []
            for value_items in value:
                row = []
                for item in value_items:
                    if item is None:
                        item = u''

                    elif isinstance(item, bool):
                        if item:
                            item = u'true'
                        else:
                            item = u'false'

                    elif isinstance(item, (int, basestring, long)):
                        item = force_unicode(item)

                    elif isinstance(item, (DATE, DATETIME)):
                        item = item.isoformat()

                    else:
                        item = dumps(item)
                        print item

                    if u'"' in item:
                        item = u'"%s"' % item.replace(u'"', u'\\"')

                    item = item.replace(separator, separator_replace)
                    item = item.replace(line_break, line_break_replace)
                    row.append(item)

                lines.append(separator.join(row))
            return line_break.join(lines)
Ejemplo n.º 16
0
        def _render(value, system):
            request = system.get('request')

            output_schema = None
            if isinstance(value, dict):
                output_schema = value['schema']
                value = value['value']

            delimiter = ';'
            quote_char = '"'
            line_terminator = '\r\n'
            quoting = QUOTE_ALL
            encoder = None

            if request is not None:
                response = request.response
                ct = response.content_type
                if ct == response.default_content_type:
                    response.content_type = 'text/csv'

                output = request.registry.config.lookup_output_schema(
                    request.matched_route.name,
                    request_method=request.method)
                if output:
                    output_schema = output[0].schema

                if output_schema:
                    value = self.lookup_rows(request, output_schema.children[0], value)

                    output_filename = getattr(output_schema, 'filename', None)
                    if output_filename:
                        if callable(output_filename):
                            output_filename = output_filename()
                        response.content_disposition = 'attachment; filename="%s"' % output_filename

                _get_param = request.params.get
                get_param = lambda k: _get_param(k) or _get_param(camelcase(k))

                csv_delimiter = get_param('csv_delimiter')
                if csv_delimiter:
                    delimiter = to_string(csv_delimiter)
                    if delimiter == '\\t':
                        delimiter = '\t'
                    else:
                        delimiter = delimiter[0]

                csv_quote_char = get_param('csv_quote_char')
                if csv_quote_char:
                    quote_char = to_string(csv_quote_char)

                csv_line_terminator = get_param('csv_line_terminator')
                if csv_line_terminator:
                    if csv_line_terminator == '\\n\\r':
                        line_terminator = '\n\r'
                    elif csv_line_terminator == '\\n':
                        line_terminator = '\n'
                    elif csv_line_terminator == '\\r':
                        line_terminator = '\r'

                csv_encoding = get_param('csv_encoding')
                if csv_encoding:
                    try:
                        encoder = codecs.lookup(csv_encoding)
                    except LookupError:
                        raise Error('csv_encoding', _('Invalid CSV encoding'))
                    else:
                        if encoder.name != 'utf-8':
                            request.response.charset = encoder.name

                yes_text = request.translate(_('Yes'))
                no_text = request.translate(_('No'))

                csv_quoting = get_param('csv_quoting')
                if csv_quoting:
                    csv_quoting = to_string(csv_quoting).lower()
                    if csv_quoting == 'minimal':
                        quoting = QUOTE_MINIMAL
                    elif csv_quoting == 'non_numeric':
                        quoting = QUOTE_NONNUMERIC
                    elif csv_quoting == 'none':
                        quoting = QUOTE_NONE

            else:
                yes_text = 'Yes'
                no_text = 'No'

            if not value:
                return ''

            f = StringIO()
            csvfile = csv_writer(
                f,
                delimiter=delimiter,
                quotechar=quote_char,
                lineterminator=line_terminator,
                quoting=quoting)

            for value_items in value:
                row = []
                for item in value_items:
                    if item is None:
                        item = ''
                    elif not isinstance(item, str):
                        if isinstance(item, bool):
                            item = item and yes_text or no_text
                        elif isinstance(item, (float, int)):
                            item = str(item)
                        elif isinstance(item, (DATE, DATETIME)):
                            item = item.isoformat()
                        elif not isinstance(item, str):
                            item = to_string(item)
                    row.append(item)
                csvfile.writerow(row)

            f.seek(0)
            response = f.read()
            f.close()

            if encoder:
                response = encoder.decode(encoder.encode(response)[0])[0]
            else:
                response = to_string(response)

            return response
Ejemplo n.º 17
0
    def get_schema_nodes(self, request):
        cache_key = 'schema build cache %s' % self.schema_route_name
        schema_expire_cache = request.settings.get('schema_expire_cache', MARKER)
        nodes = request.cache.get(cache_key, MARKER, expire=schema_expire_cache)
        if nodes is MARKER:
            nodes = defaultdict(dict)
            global_types = defaultdict(list)
            global_models = defaultdict(list)
            keep_types_keys = defaultdict(set)
            keep_models_keys = defaultdict(set)
            to_translate = defaultdict(list)

            for route_name in self.get_route_names():
                info = self.get_route_info(request, route_name)
                if not info:
                    continue

                intr_route, url, url_keys = info
                url_keys = [camelcase(k) for k in url_keys]
                schemas = request.registry.config.lookup_input_schema(route_name, self.request_methods)
                schemas.extend(request.registry.config.lookup_output_schema(route_name, self.request_methods))

                for schema in schemas:
                    fields = []
                    types = defaultdict(list)
                    models = defaultdict(list)

                    if schema.schema:
                        details = self.construct_structure(
                            request,
                            schema.schema,
                            schema.schema_type,
                            types,
                            models,
                            to_translate)

                        if isinstance(details, dict):
                            fields.append(details)
                        else:
                            fields.extend(details)

                    if schema.schema_type == 'request' and schema.fields_schema:
                        details = self.construct_structure(
                            request,
                            schema.fields_schema,
                            schema.schema_type,
                            types,
                            models,
                            to_translate)

                        if isinstance(details, dict):
                            fields.append(details)
                        else:
                            fields.extend(details)

                    if schema.route_name != self.csv_route_name:
                        key = schema.request_method.lower()
                        if key == 'get' and schema.route_name == self.list_route_name:
                            key = 'list'
                    else:
                        key = 'csv'

                    nodes[key][schema.schema_type] = fields
                    nodes[key]['routeName'] = route_name
                    nodes[key]['method'] = schema.request_method.upper()
                    nodes[key]['url'] = url
                    nodes[key]['urlKeys'] = url_keys
                    nodes[key]['renderer'] = schema.renderer.lower()

                    if types:
                        keep_types_keys[key].update(types.keys())
                        for k, values in types.items():
                            global_types[k].extend(values)
                    if models:
                        keep_models_keys[key].update(models.keys())
                        for k, values in models.items():
                            global_models[k].extend(values)

            if global_types:
                if to_translate:
                    to_translate['fieldTypes'] = defaultdict(set)
                nodes['fieldTypes'] = lookup_common_fields(
                    global_types,
                    to_translate,
                    ignore_key='fieldType',
                    is_field_type=True)
                nodes['keep_types_keys'] = keep_types_keys

            if global_models:
                if to_translate:
                    to_translate['models'] = defaultdict(set)
                nodes['models'] = lookup_common_fields(global_models, to_translate, ignore_key='model')
                nodes['keep_models_keys'] = keep_models_keys

            if to_translate:
                nodes['to_translate'] = to_translate

            request.cache.put(cache_key, nodes, expire=schema_expire_cache)

        permissions_cache = {}
        types_keys = set()
        types = nodes.pop('fieldTypes', None)
        keep_types_keys = nodes.pop('keep_types_keys', None)
        models_keys = set()
        models = nodes.pop('models', None)
        keep_models_keys = nodes.pop('keep_models_keys', None)

        to_translate = nodes.pop('to_translate', None)
        fields_translation = {}
        models_translation = {}
        if to_translate:
            translator = request.translator
            fields_translation = to_translate.pop('fieldTypes', fields_translation)
            models_translation = to_translate.pop('models', fields_translation)

        for key, details in nodes.items():
            route_name = details['routeName']
            if route_name not in permissions_cache:
                info = self.get_route_info(request, route_name)
                permissions_cache[route_name] = lookup_for_route_permissions(request.registry, info[0])

            method_permissions = maybe_list(permissions_cache[route_name].get(details['method']))
            if not self.validate_permission(request, method_permissions):
                nodes.pop(key)
                continue

            if keep_types_keys:
                types_keys.update(keep_types_keys[key])
            if keep_models_keys:
                models_keys.update(keep_models_keys[key])

        if types_keys:
            nodes['fieldTypes'] = {}
            for k in types_keys:
                nodes['fieldTypes'][k] = details = types[k]
                field_fields = fields_translation.get(k)
                if field_fields:
                    for field in field_fields:
                        if field == 'options':
                            for option in details[field]:
                                if option['text']:
                                    option['text'] = translator(option['text'])
                        else:
                            details[field] = translator(details[field])

        if models_keys:
            nodes['models'] = {}
            for k in models_keys:
                nodes['models'][k] = details = models[k]
                model_fields = models_translation.get(k)
                if model_fields:
                    for field in model_fields:
                        if field == 'options':
                            for option in details[field]:
                                if option['text']:
                                    option['text'] = translator(option['text'])
                        else:
                            details[field] = translator(details[field])

        if to_translate:
            for key, values in to_translate.items():
                for value in values:
                    text_value = value.get(key)
                    if text_value:
                        value[key] = translator(text_value)
                        print(text_value, value[key])

        return nodes
Ejemplo n.º 18
0
def get_colander_type_name(node):
    if hasattr(node, 'schema_type_name'):
        return node.schema_type_name
    else:
        return camelcase(str(node.__class__.__name__).lower())
Ejemplo n.º 19
0
    def construct_structure(self, request, schema, schema_type, types, models, to_translate, parent_name=None):
        if isinstance(schema.typ, Sequence):
            child = schema.children[0]
            if not schema.name:
                schema = child

            name = camelcase(schema.name)
            details = {
                'model': name,
                'type': 'sequence',
                'title': schema.title,
                'description': schema.description or ''}
            models[name].append(details)

            if isinstance(schema.title, TranslationString):
                to_translate['title'].append(details)
            if isinstance(schema.description, TranslationString):
                to_translate['description'].append(details)

            # Find and add child
            child_details = self.construct_structure(
                request,
                child,
                schema_type,
                types,
                models,
                to_translate,
                parent_name=schema.name)

            if isinstance(details, dict):
                if isinstance(child.typ, Mapping):
                    details['type'] = 'model'
                    details.update(child_details)
                else:
                    details['fields'] = [child_details]
            else:
                details['fields'] = child_details

            return details

        elif isinstance(schema.typ, Tuple):
            raise NotImplementedError('Tuple type need to be implemented')

        elif isinstance(schema.typ, Mapping):
            fields = []
            for child in schema.children:
                fields.append(self.construct_structure(
                    request,
                    child,
                    schema_type,
                    types,
                    models,
                    to_translate,
                    parent_name=schema.name))

            name = schema.name or parent_name
            if not name:
                return fields

            name = camelcase(name)
            details = {
                'type': 'model',
                'title': schema.title,
                'description': schema.description or '',
                'fields': fields,
                'model': name}
            models[name].append(details)

            if isinstance(schema.title, TranslationString):
                to_translate['title'].append(details)
            if isinstance(schema.description, TranslationString):
                to_translate['description'].append(details)

            return details

        else:
            name = camelcase(schema.name)
            details = {
                'fieldType': name,
                'title': schema.title,
                'description': schema.description or ''}

            if isinstance(schema.title, TranslationString):
                to_translate['title'].append(details)
            if isinstance(schema.description, TranslationString):
                to_translate['description'].append(details)

            if hasattr(schema, 'model_reference'):
                model = schema.model_reference['model']
                model_key = schema.model_reference.get('key') or 'key'
                model_query = schema.model_reference.get('query') or 'name'
                model_application = schema.model_reference.get('application_name') or request.application_name
                details['modelReference'] = {
                    'applicationName': model_application,
                    'schemaName': schema.model_reference['schema'],
                    'key': camelcase(model[model_key].name),
                    'model': camelcase(model.name),
                    'queryField': camelcase(model[model_query].name)}

            types[name].append(details)

            if isinstance(schema.typ, FilterByType):
                for cls in schema.typ.__class__.__mro__[1:]:
                    if cls is not FilterByType:
                        details['type'] = str(cls.__name__).lower()
                        break
                details['filter'] = True
            elif hasattr(schema, 'schema_type_name'):
                details['type'] = camelcase(schema.schema_type_name)
            else:
                details['type'] = get_colander_type_name(schema.typ)

            request_validation = []
            if schema.validator:
                if isinstance(schema.validator, All):
                    validators = schema.validator.validators
                elif not is_nonstr_iter(schema.validator):
                    validators = [schema.validator]
                else:
                    validators = schema.validator

                for validator in validators:
                    if isinstance(validator, OneOfWithDescription):
                        details['options'] = []
                        add_option = details['options'].append
                        save_to_translate = False
                        for choice, description in validator.choices_with_descripton:
                            add_option({'value': choice, 'text': description})
                            save_to_translate = save_to_translate or isinstance(description, TranslationString)
                        if save_to_translate:
                            to_translate['options'].append(details)

                    elif isinstance(validator, OneOf):
                        details['options'] = []
                        add_option = details['options'].append
                        for choice in validator.choices:
                            add_option({
                                'value': choice,
                                'text': choice.replace('_', ' ').title()})

                    else:
                        if isinstance(validator, Length):
                            validation_option = {}
                            if validator.min is not None:
                                validation_option['min'] = validator.min
                            if validator.max is not None:
                                validation_option['max'] = validator.max
                        else:
                            validation_option = True

                        request_validation.append((validator, validation_option))

            if hasattr(schema, 'use_when'):
                details['useWhen'] = {camelcase(k): v for k, v in schema.use_when.items()}

            if schema_type == 'request':
                validation = {}
                if schema.required:
                    validation['required'] = True

                if request_validation:
                    for validator, validation_option in request_validation:
                        validation[get_colander_type_name(validator)] = validation_option
                if validation:
                    details['validation'] = validation

                default = schema.missing
            else:
                if schema.missing is drop:
                    details['maybeNotSent'] = True
                default = schema.default

            if (default is not drop
                    and default is not required
                    and default is not null):
                if isinstance(schema.typ, Number):
                    default = schema.typ.num(default)
                elif isinstance(schema.typ, BaseBoolean):
                    default = asbool(default)
                details['default'] = default

            return details
Ejemplo n.º 20
0
    def construct_structure(self, request, schema, schema_type, types, models, to_translate, parent_name=None):
        if isinstance(schema.typ, Sequence):
            child = schema.children[0]
            if not schema.name:
                schema = child

            name = camelcase(schema.name)
            details = {
                "model": name,
                "type": "sequence",
                "title": schema.title,
                "description": schema.description or EMPTY_STRING,
            }
            models[name].append(details)

            if isinstance(schema.title, TranslationString):
                to_translate["title"].append(details)
            if isinstance(schema.description, TranslationString):
                to_translate["description"].append(details)

            # Find and add child
            child_details = self.construct_structure(
                request, child, schema_type, types, models, to_translate, parent_name=schema.name
            )

            if isinstance(details, dict):
                if isinstance(child.typ, Mapping):
                    details["type"] = "model"
                    details.update(child_details)
                else:
                    details["fields"] = [child_details]
            else:
                details["fields"] = child_details

            return details

        elif isinstance(schema.typ, Tuple):
            raise NotImplementedError("Tuple type need to be implemented")

        elif isinstance(schema.typ, Mapping):
            fields = []
            for child in schema.children:
                fields.append(
                    self.construct_structure(
                        request, child, schema_type, types, models, to_translate, parent_name=schema.name
                    )
                )

            name = schema.name or parent_name
            if not name:
                return fields

            name = camelcase(name)
            details = {
                "type": "model",
                "title": schema.title,
                "description": schema.description or EMPTY_STRING,
                "fields": fields,
                "model": name,
            }
            models[name].append(details)

            if isinstance(schema.title, TranslationString):
                to_translate["title"].append(details)
            if isinstance(schema.description, TranslationString):
                to_translate["description"].append(details)

            return details

        else:
            name = camelcase(schema.name)
            details = {"fieldType": name, "title": schema.title, "description": schema.description or EMPTY_STRING}

            if isinstance(schema.title, TranslationString):
                to_translate["title"].append(details)
            if isinstance(schema.description, TranslationString):
                to_translate["description"].append(details)

            if hasattr(schema, "model_reference"):
                model = schema.model_reference["model"]
                model_key = schema.model_reference.get("key") or "key"
                model_query = schema.model_reference.get("query") or "name"
                model_application = schema.model_reference.get("application_name") or request.application_name
                details["modelReference"] = {
                    "applicationName": model_application,
                    "schemaName": schema.model_reference["schema"],
                    "key": camelcase(model[model_key].name),
                    "model": camelcase(model.name),
                    "queryField": camelcase(model[model_query].name),
                }

            types[name].append(details)

            if isinstance(schema.typ, FilterByType):
                for cls in schema.typ.__class__.__mro__[1:]:
                    if cls is not FilterByType:
                        details["type"] = str(cls.__name__).lower()
                        break
                details["filter"] = True
            elif hasattr(schema, "schema_type_name"):
                details["type"] = camelcase(schema.schema_type_name)
            else:
                details["type"] = get_colander_type_name(schema.typ)

            request_validation = []
            if schema.validator:
                if isinstance(schema.validator, All):
                    validators = schema.validator.validators
                elif not is_nonstr_iter(schema.validator):
                    validators = [schema.validator]
                else:
                    validators = schema.validator

                for validator in validators:
                    if isinstance(validator, OneOfWithDescription):
                        details["options"] = []
                        add_option = details["options"].append
                        save_to_translate = False
                        for choice, description in validator.choices_with_descripton:
                            add_option({"value": choice, "text": description})
                            save_to_translate = save_to_translate or isinstance(description, TranslationString)
                        if save_to_translate:
                            to_translate["options"].append(details)

                    elif isinstance(validator, OneOf):
                        details["options"] = []
                        add_option = details["options"].append
                        for choice in validator.choices:
                            add_option({"value": choice, "text": to_unicode(choice).replace(UNDERSCORE, SPACE).title()})

                    else:
                        if isinstance(validator, Length):
                            validation_option = {}
                            if validator.min is not None:
                                validation_option["min"] = validator.min
                            if validator.max is not None:
                                validation_option["max"] = validator.max
                        else:
                            validation_option = True

                        request_validation.append((validator, validation_option))

            if hasattr(schema, "use_when"):
                details["useWhen"] = dict((camelcase(k), v) for k, v in schema.use_when.items())

            if schema_type == "request":
                validation = {}
                if schema.required:
                    validation["required"] = True

                if request_validation:
                    for validator, validation_option in request_validation:
                        validation[get_colander_type_name(validator)] = validation_option
                if validation:
                    details["validation"] = validation

                default = schema.missing
            else:
                if schema.missing is drop:
                    details["maybeNotSent"] = True
                default = schema.default

            if default is not drop and default is not required and default is not null:
                if isinstance(schema.typ, Number):
                    default = schema.typ.num(default)
                elif isinstance(schema.typ, BaseBoolean):
                    default = asbool(default)
                details["default"] = default

            return details
Ejemplo n.º 21
0
        def _render(value, system):
            request = system.get('request')
            if request is not None:
                response = request.response
                ct = response.content_type
                if ct == response.default_content_type:
                    response.content_type = 'text/csv'

                output = request.registry.config.lookup_output_schema(
                    request.matched_route.name,
                    request_method=request.method)
                if output:
                    output = output[0]
                    node = output.schema.children[0]
                    value_lines = []

                    header = []
                    value_lines.append(header)
                    for child in node.children:
                        header.append(child.title)

                    for item_value in value:
                        row = []
                        value_lines.append(row)

                        if isinstance(item_value, dict):
                            for child in node.children:
                                row.append(item_value.get(camelcase(child.name)))
                        else:
                            for child in node.children:
                                row.append(getattr(item_value, child.name, None))

                    value = value_lines

            separator = u';'
            separator_replace = u','
            line_break = u'\n'
            line_break_replace = u' '

            lines = []
            for value_items in value:
                row = []
                for item in value_items:
                    if item is None:
                        item = u''

                    elif isinstance(item, bool):
                        if item:
                            item = u'true'
                        else:
                            item = u'false'

                    elif isinstance(item, (int, basestring, long)):
                        item = force_unicode(item)

                    elif isinstance(item, (DATE, DATETIME)):
                        item = item.isoformat()

                    else:
                        item = dumps(item)
                        print item

                    if u'"' in item:
                        item = u'"%s"' % item.replace(u'"', u'\\"')

                    item = item.replace(separator, separator_replace)
                    item = item.replace(line_break, line_break_replace)
                    row.append(item)

                lines.append(separator.join(row))
            return line_break.join(lines)