Exemplo n.º 1
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}
Exemplo n.º 2
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