Exemple #1
0
def collection_entity_save(collection):
    collection = get_collection(collection, authz.WRITE)
    data = request_data()
    update_operation = 'id' in data

    entities = get_loom_config().entities
    schema = data.get('$schema')
    if update_operation and schema is None:
        schema = entities.get_schema(data['id'], right=authz.entity_right())

    if schema not in get_loom_config().schemas.values():
        raise BadRequest()

    # this will raise if it fails:
    validate(data, schema)
    subject = entities.save(schema,
                            data,
                            collection_id=collection.id,
                            author=request.auth_user,
                            right=authz.entity_right())
    collection_add_entity(collection, subject)
    get_loom_indexer().index_one(subject, schema=schema)
    entity = entities.get(subject,
                          schema=schema,
                          depth=2,
                          right=authz.entity_right())
    return jsonify({
        'status': 'ok',
        'data': entity
    },
                   status=200 if update_operation else 201)
Exemple #2
0
def collection_entity_save(collection):
    collection = get_collection(collection, authz.WRITE)
    data = request_data()
    update_operation = 'id' in data

    entities = get_loom_config().entities
    schema = data.get('$schema')
    if update_operation and schema is None:
        schema = entities.get_schema(data['id'], right=authz.entity_right())

    if schema not in get_loom_config().schemas.values():
        raise BadRequest()

    # this will raise if it fails:
    validate(data, schema)
    subject = entities.save(schema, data, collection_id=collection.id,
                            author=request.auth_user,
                            right=authz.entity_right())
    collection_add_entity(collection, subject)
    get_loom_indexer().index_one(subject, schema=schema)
    entity = entities.get(subject, schema=schema, depth=2,
                          right=authz.entity_right())
    return jsonify({
        'status': 'ok',
        'data': entity
    }, status=200 if update_operation else 201)
Exemple #3
0
def collection_graph(collection):
    collection = get_collection(collection, authz.READ)
    network = Network(get_loom_config().resolver)
    schema = request.args.get('$schema')
    for entity in collection_entities(collection, depth=get_depth(3),
                                      filter_schema=schema):
        network.add(entity)
    return jsonify(network)
Exemple #4
0
def collection_remove_entity(collection, subject):
    q = session.query(CollectionSubject).filter_by(subject=subject)
    q = q.filter_by(collection_id=collection.id)
    q.delete()
    session.commit()

    entities = get_loom_config().entities
    entities.remove(subject, collection_id=collection.id)
Exemple #5
0
def collection_graph(collection):
    collection = get_collection(collection, authz.READ)
    network = Network(get_loom_config().resolver)
    schema = request.args.get('$schema')
    for entity in collection_entities(collection,
                                      depth=get_depth(3),
                                      filter_schema=schema):
        network.add(entity)
    return jsonify(network)
Exemple #6
0
def collection_entities(collection, depth=2, filter_schema=None):
    config = get_loom_config()
    # FIXME: this is a performance nightmare. Think about how to fix it.
    results = []
    q = config.entities.subjects(schema=filter_schema,
                                 collection_id=collection.id,
                                 right=authz.entity_right())
    for (subject, schema) in q:
        data = config.entities.get(subject, schema=schema, depth=depth,
                                   right=authz.entity_right())
        results.append(result_entity(data))
    return results
Exemple #7
0
def collection_entities(collection, depth=2, filter_schema=None):
    config = get_loom_config()
    # FIXME: this is a performance nightmare. Think about how to fix it.
    results = []
    q = config.entities.subjects(schema=filter_schema,
                                 collection_id=collection.id,
                                 right=authz.entity_right())
    for (subject, schema) in q:
        data = config.entities.get(subject,
                                   schema=schema,
                                   depth=depth,
                                   right=authz.entity_right())
        results.append(result_entity(data))
    return results
Exemple #8
0
def update_subjects(collection, data):
    """ There must be a nicer way to do this in SQLA. """
    # TODO: authz
    subjects = data.get('subjects', [])
    for cs in collection.subjects:
        if cs.subject in subjects:
            subjects.remove(cs.subject)
        else:
            session.delete(cs)
    for subject in subjects:
        if get_loom_config().entities.get_schema(subject):
            cs = CollectionSubject(collection, subject)
            session.add(cs)
        else:
            raise BadRequest()
Exemple #9
0
def suggest_entity(args):
    """ Auto-complete API. """
    config = get_loom_config()
    text = args.get('text')
    options = []
    if text is not None and len(text.strip()):
        q = authz_filter({'match': {'$suggest': text}})
        schema = args.get('$schema')
        if schema is not None:
            # Find matching sub-schemas as well.
            schemas = config.implied_schemas(schema)
            q = add_filter(q, {"terms": {"$schema": schemas}})
        boost_collection = args.get('boost_collection')
        if boost_collection is not None:
            q = {
                'function_score': {
                    'query': q,
                    'functions': [{
                        'boost_factor': 2,
                        'filter': {
                            'term': {
                                '$collections': boost_collection
                            }
                        }
                    }]
                }
            }
        exclude_collection = args.get('exclude_collection')
        if exclude_collection is not None:
            q = add_filter(q, {'not': {
                'term': {'$collections': exclude_collection}
            }})
        q = {
            'size': 5,
            'query': q,
            '_source': ['name', 'id', '$schema']
        }
        result = get_es().search(index=get_es_index(), body=q)
        for res in result.get('hits', {}).get('hits', []):
            options.append(res.get('_source'))
    return {
        'text': text,
        'options': options
    }
Exemple #10
0
def suggest_entity(args):
    """ Auto-complete API. """
    config = get_loom_config()
    text = args.get('text')
    options = []
    if text is not None and len(text.strip()):
        q = authz_filter({'match': {'$suggest': text}})
        schema = args.get('$schema')
        if schema is not None:
            # Find matching sub-schemas as well.
            schemas = config.implied_schemas(schema)
            q = add_filter(q, {"terms": {"$schema": schemas}})
        boost_collection = args.get('boost_collection')
        if boost_collection is not None:
            q = {
                'function_score': {
                    'query':
                    q,
                    'functions': [{
                        'boost_factor': 2,
                        'filter': {
                            'term': {
                                '$collections': boost_collection
                            }
                        }
                    }]
                }
            }
        exclude_collection = args.get('exclude_collection')
        if exclude_collection is not None:
            q = add_filter(
                q, {'not': {
                    'term': {
                        '$collections': exclude_collection
                    }
                }})
        q = {'size': 5, 'query': q, '_source': ['name', 'id', '$schema']}
        result = get_es().search(index=get_es_index(), body=q)
        for res in result.get('hits', {}).get('hits', []):
            options.append(res.get('_source'))
    return {'text': text, 'options': options}
    def test_basic_search(self):
        self.setUpFixtures()
        config = get_loom_config()
        assert len(config.types), len(config.types)

        res = self.client.get('/api/search')
        assert res.json['total'] == 0, res.json

        self.login()
        res = self.client.get('/api/search')
        assert res.json['total'] == 50, res.json

        res = self.client.get('/api/search?limit=4')
        assert len(res.json['results']) == 4, res.json

        res = self.client.get('/api/search?offset=46')
        assert len(res.json['results']) == 4, res.json

        res = self.client.get('/api/search?q=Hazim')
        assert res.json['total'] == 1, res.json['total']
        assert not res.json['facets'], res.json['total']

        res = self.client.get('/api/search?facet=jurisdiction_code')
        facets = res.json['facets']
        assert 'jurisdiction_code' in facets, facets
        jur = facets['jurisdiction_code']
        assert jur['values'][0]['key'] == 'BA', facets

        ORG = "https://schema.occrp.org/generic/organization.json#"
        res = self.client.get('/api/search?filter:$schema=' + ORG)
        assert res.json['total'] == 8, res.json['total']

        qs = '?filter:jurisdiction_code=BA&filter:$schema=' + ORG
        res = self.client.get('/api/search' + qs)
        assert res.json['total'] == 8, res.json['total']

        qs = '?filter:jurisdiction_code=GB&filter:$schema=' + ORG
        res = self.client.get('/api/search' + qs)
        assert res.json['total'] == 0, res.json['total']
Exemple #12
0
def entities_to_table(schema, entities):
    """ Generate a flattened table from a set of entities, inlining
    inline sub-entities. """
    config = get_loom_config()
    visitor = SchemaVisitor({'$ref': schema}, config.resolver)
    rows = []
    for entity in entities:
        row = OrderedDict()
        for prop in visitor.properties:
            if prop.is_value and prop.inline:
                row[prop.title] = entity.get(prop.name)
            if prop.is_object:
                child_entity = entity.get(prop.name, {})
                if prop.inline:
                    for child_prop in prop.properties:
                        if not prop.inline:
                            continue
                        title = '%s: %s' % (prop.title, child_prop.title)
                        row[title] = child_entity.get(child_prop.name)
                else:
                    row[prop.title] = child_entity.get('name',
                                                       child_entity.get('id'))
        rows.append(row)
    return visitor, rows
Exemple #13
0
def entities_to_table(schema, entities):
    """ Generate a flattened table from a set of entities, inlining
    inline sub-entities. """
    config = get_loom_config()
    visitor = SchemaVisitor({'$ref': schema}, config.resolver)
    rows = []
    for entity in entities:
        row = OrderedDict()
        for prop in visitor.properties:
            if prop.is_value and prop.inline:
                row[prop.title] = entity.get(prop.name)
            if prop.is_object:
                child_entity = entity.get(prop.name, {})
                if prop.inline:
                    for child_prop in prop.properties:
                        if not prop.inline:
                            continue
                        title = '%s: %s' % (prop.title, child_prop.title)
                        row[title] = child_entity.get(child_prop.name)
                else:
                    row[prop.title] = child_entity.get('name',
                                                       child_entity.get('id'))
        rows.append(row)
    return visitor, rows
Exemple #14
0
def validate(data, schema):
    resolver = get_loom_config().resolver
    _, schema = resolver.resolve(schema)
    validator = Draft4Validator(schema, resolver=resolver,
                                format_checker=format_checker)
    return validator.validate(data, schema)
Exemple #15
0
def view(id):
    entities = get_loom_config().entities
    data = obj_or_404(entities.get(id, depth=get_depth(3),
                                   right=authz.entity_right()))
    return jsonify({'status': 'ok', 'data': result_entity(data)})
Exemple #16
0
def view(id):
    entities = get_loom_config().entities
    data = obj_or_404(
        entities.get(id, depth=get_depth(3), right=authz.entity_right()))
    return jsonify({'status': 'ok', 'data': result_entity(data)})