Beispiel #1
0
 def make_fixtures(self):
     self.app.post('/api/1/networks',
                 headers=AUTHZ_HEADER,
                 data=NETWORK_FIXTURE)
     network = Network.by_slug(NETWORK_FIXTURE['slug'])
     Schema.create(network, Schema.RELATION,
                   h.TEST_RELATION_SCHEMA)
     Schema.create(network, Schema.ENTITY,
                   h.TEST_ENTITY_SCHEMA)
     res = self.app.post('/api/1/net/entities', 
                 headers=AUTHZ_HEADER,
                 data=ENTITY1_FIXTURE, 
                 follow_redirects=True)
     body = json.loads(res.data)
     self.source_id = body['id']
     res = self.app.post('/api/1/net/entities',
                 headers=AUTHZ_HEADER,
                 data=ENTITY2_FIXTURE, 
                 follow_redirects=True)
     body = json.loads(res.data)
     self.target_id = body['id']
     RELATION_FIXTURE['source'] = self.source_id
     RELATION_FIXTURE['target'] = self.target_id
     res = self.app.post('/api/1/net/relations', 
                 headers=AUTHZ_HEADER,
                 data=RELATION_FIXTURE, 
                 follow_redirects=True)
     print res.data
     body = json.loads(res.data)
     self.id = body['id']
Beispiel #2
0
 def make_fixtures(self):
     self.app.post('/api/1/networks',
                   headers=AUTHZ_HEADER,
                   data=NETWORK_FIXTURE)
     network = Network.by_slug(NETWORK_FIXTURE['slug'])
     Schema.create(network, Schema.RELATION, h.TEST_RELATION_SCHEMA)
     Schema.create(network, Schema.ENTITY, h.TEST_ENTITY_SCHEMA)
     res = self.app.post('/api/1/net/entities',
                         headers=AUTHZ_HEADER,
                         data=ENTITY1_FIXTURE,
                         follow_redirects=True)
     body = json.loads(res.data)
     self.source_id = body['id']
     res = self.app.post('/api/1/net/entities',
                         headers=AUTHZ_HEADER,
                         data=ENTITY2_FIXTURE,
                         follow_redirects=True)
     body = json.loads(res.data)
     self.target_id = body['id']
     RELATION_FIXTURE['source'] = self.source_id
     RELATION_FIXTURE['target'] = self.target_id
     res = self.app.post('/api/1/net/relations',
                         headers=AUTHZ_HEADER,
                         data=RELATION_FIXTURE,
                         follow_redirects=True)
     print res.data
     body = json.loads(res.data)
     self.id = body['id']
Beispiel #3
0
 def setUp(self):
     self.app = make_test_app()
     self.app.post('/api/1/networks',
                   headers=AUTHZ_HEADER,
                   data=NETWORK_FIXTURE)
     network = Network.by_slug(NETWORK_FIXTURE['slug'])
     Schema.create(network, Schema.RELATION, h.TEST_RELATION_SCHEMA)
     Schema.create(network, Schema.ENTITY, h.TEST_ENTITY_SCHEMA)
     db.session.commit()
Beispiel #4
0
 def setUp(self):
     self.client = h.make_test_app()
     self.network = Network.create({'title': 'Net', 'slug': 'net'})
     self.schema = Schema.create(self.network, Schema.ENTITY,
                                 h.TEST_ENTITY_SCHEMA)
     self.rschema = Schema.create(self.network, Schema.RELATION,
                                  h.TEST_RELATION_SCHEMA)
     db.session.commit()
     self.context = ValidationContext(network=self.network)
Beispiel #5
0
 def setUp(self):
     self.client = h.make_test_app()
     self.network = Network.create({'title': 'Net', 'slug': 'net'})
     self.schema = Schema.create(self.network, Schema.ENTITY,
                                 h.TEST_ENTITY_SCHEMA)
     self.rschema = Schema.create(self.network, Schema.RELATION,
                                 h.TEST_RELATION_SCHEMA)
     db.session.commit()
     self.context = ValidationContext(network=self.network)
Beispiel #6
0
 def decode(self, node, cstruct):
     if isinstance(cstruct, Schema):
         return cstruct
     if isinstance(cstruct, basestring):
         return Schema.by_name(self.project, cstruct)
     if isinstance(cstruct, dict):
         if cstruct.get('name'):
             return Schema.by_name(self.project, cstruct.get('name'))
     return None
Beispiel #7
0
 def decode(self, node, cstruct):
     if isinstance(cstruct, Schema):
         return cstruct
     if isinstance(cstruct, basestring):
         return Schema.by_name(self.project, cstruct)
     if isinstance(cstruct, dict):
         if cstruct.get('name'):
             return Schema.by_name(self.project,
                 cstruct.get('name'))
     return None
Beispiel #8
0
def save(data, schema=None):
    """ Create a schema. """

    schema_val = SchemaValidator(validator=check_attributes)
    data = schema_val.deserialize(data)

    if schema is None:
        schema = Schema()
        schema.name = data.get('name')
        schema.project = data.get('project')

    schema.label = data.get('label')
    schema.label_in = data.get('label_in') or schema.label
    schema.label_out = data.get('label_out') or schema.label

    schema.obj = data.get('obj')
    schema.hidden = data.get('hidden')
    schema.project.updated_at = datetime.utcnow()
    db.session.add(schema)

    names = []
    for attribute in data.get('attributes', []):
        attribute['schema'] = schema
        attr = attributes.save(attribute)
        schema.attributes.append(attr)
        names.append(attr.name)

    for attr in schema.attributes:
        if attr.name not in names:
            db.session.delete(attr)

    return schema
Beispiel #9
0
 def setUp(self):
     self.app = make_test_app()
     self.app.post('/api/1/networks',
                 headers=AUTHZ_HEADER,
                 data=NETWORK_FIXTURE)
     network = Network.by_slug(NETWORK_FIXTURE['slug'])
     Schema.create(network, Schema.RELATION,
                   h.TEST_RELATION_SCHEMA)
     Schema.create(network, Schema.ENTITY,
                   h.TEST_ENTITY_SCHEMA)
     db.session.commit()
Beispiel #10
0
def save(data, schema=None):
    """ Create a schema. """

    schema_val = SchemaValidator(validator=check_attributes)
    data = schema_val.deserialize(data)

    if schema is None:
        schema = Schema()
        schema.name = data.get('name')
        schema.project = data.get('project')

    schema.label = data.get('label')
    schema.label_in = data.get('label_in') or schema.label
    schema.label_out = data.get('label_out') or schema.label

    schema.obj = data.get('obj')
    schema.hidden = data.get('hidden')
    schema.project.updated_at = datetime.utcnow()
    db.session.add(schema)
    
    names = []
    for attribute in data.get('attributes', []):
        attribute['schema'] = schema
        attr = attributes.save(attribute)
        schema.attributes.append(attr)
        names.append(attr.name)

    for attr in schema.attributes:
        if attr.name not in names:
            attributes.delete(attr)

    return schema
Beispiel #11
0
 def make_fixtures(self):
     self.app.post('/api/1/networks',
                   headers=AUTHZ_HEADER,
                   data=NETWORK_FIXTURE)
     network = Network.by_slug(NETWORK_FIXTURE['slug'])
     Schema.create(network, Schema.RELATION, h.TEST_RELATION_SCHEMA)
     Schema.create(network, Schema.ENTITY, h.TEST_ENTITY_SCHEMA)
     db.session.commit()
     res = self.app.post('/api/1/net/entities',
                         headers=AUTHZ_HEADER,
                         data=ENTITY_FIXTURE,
                         follow_redirects=True)
     body = json.loads(res.data)
     self.id = body['id']
Beispiel #12
0
def apply_alias(project, author, canonical_name, alias_name):
    """ Given two names, find out if there are existing entities for one or 
    both of them. If so, merge them into a single entity - or, if only the 
    entity associated with the alias exists - re-name the entity. """

    canonical_name = canonical_name.strip()

    # Don't import meaningless aliases.
    if canonical_name == alias_name or not len(canonical_name):
        return log.info("No alias: %s", canonical_name)

    canonical = Entity.by_name(project, canonical_name)
    alias = Entity.by_name(project, alias_name)
    schema = Schema.by_name(project, 'base')

    # Don't artificially increase entity counts.
    if canonical is None and alias is None:
        return log.info("Neither alias nor canonical exist: %s", canonical_name)

    # Rename an alias to its new, canonical name.
    if canonical is None:
        properties_logic.set(alias, author, 'name', schema, canonical_name,
            active=True, source_url=None)
        _entity_changed.delay(alias.id)
        return log.info("Renamed: %s", alias_name)

    # Already done, thanks.
    if canonical == alias:
        return log.info("Already aliased: %s", canonical_name)

    # Merge two existing entities, declare one as "same_as"
    if canonical is not None and alias is not None:
        _merge_entities(alias, canonical)
        _entity_changed.delay(canonical.id)
        return log.info("Mapped: %s -> %s", alias.id, canonical.id)
Beispiel #13
0
def delete(slug, name):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_manage(project))
    schema = object_or_404(Schema.by_name(project, name))
    schemata.delete(schema)
    db.session.commit()
    raise Gone()
Beispiel #14
0
def view(slug, name):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_read(project))
    if not project.private:
        validate_cache(last_modified=project.updated_at)
    schema = object_or_404(Schema.by_name(project, name))
    return jsonify(schema)
Beispiel #15
0
def delete(slug, name):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_manage(project))
    schema = object_or_404(Schema.by_name(project, name))
    schemata.delete(schema)
    db.session.commit()
    raise Gone()
Beispiel #16
0
def view(slug, name):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_read(project))
    if not project.private:
        validate_cache(last_modified=project.updated_at)
    schema = object_or_404(Schema.by_name(project, name))
    return jsonify(schema)
Beispiel #17
0
 def make_fixtures(self):
     self.app.post('/api/1/networks',
                 headers=AUTHZ_HEADER,
                 data=NETWORK_FIXTURE)
     network = Network.by_slug(NETWORK_FIXTURE['slug'])
     Schema.create(network, Schema.RELATION,
                   h.TEST_RELATION_SCHEMA)
     Schema.create(network, Schema.ENTITY,
                   h.TEST_ENTITY_SCHEMA)
     db.session.commit()
     res = self.app.post('/api/1/net/entities', 
                 headers=AUTHZ_HEADER,
                 data=ENTITY_FIXTURE, 
                 follow_redirects=True)
     body = json.loads(res.data)
     self.id = body['id']
Beispiel #18
0
def update(slug, name):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_manage(project))
    schema = object_or_404(Schema.by_name(project, name))
    data = request_data({'project': project})
    schema = schemata.save(data, schema=schema)
    db.session.commit()
    return jsonify(schema)
Beispiel #19
0
def index(slug):
    project = object_or_404(Project.by_slug(slug))
    validate_cache(last_modified=project.updated_at)
    query = Schema.all()
    query = query.filter_by(project=project)
    pager = Pager(query)
    conv = lambda es: [schemata.to_rest_index(e) for e in es]
    return jsonify(pager.to_dict(conv))
Beispiel #20
0
def index(slug):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_read(project))
    validate_cache(last_modified=project.updated_at)
    query = Schema.all()
    query = query.filter_by(project=project)
    pager = Pager(query, slug=slug)
    return jsonify(pager, index=not arg_bool("full"))
Beispiel #21
0
def update(slug, name):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_manage(project))
    schema = object_or_404(Schema.by_name(project, name))
    data = request_data({'project': project})
    project = schemata.save(data, schema=schema)
    db.session.commit()
    return jsonify(schemata.to_rest(schema))
def facet_schema_list(obj, facets):
    results = []
    project = Project.by_slug('openinterests')
    for facet in facets:
        schema = Schema.by_name(project, facet.get('term'))
        if schema is not None and not schema.hidden:
            results.append((schema, facet.get('count')))
    return results
Beispiel #23
0
def index(slug):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_read(project))
    validate_cache(last_modified=project.updated_at)
    query = Schema.all()
    query = query.filter_by(project=project)
    pager = Pager(query, slug=slug)
    return jsonify(pager, index=not arg_bool('full'))
Beispiel #24
0
def index(slug):
    project = object_or_404(Project.by_slug(slug))
    validate_cache(last_modified=project.updated_at)
    query = Schema.all()
    query = query.filter_by(project=project)
    pager = Pager(query)
    conv = lambda es: [schemata.to_rest_index(e) for e in es]
    return jsonify(pager.to_dict(conv))
Beispiel #25
0
 def setUp(self):
     self.client = h.make_test_app()
     self.network = Network.create({'title': 'Net', 'slug': 'net'})
     self.schema = Schema.create(self.network, Schema.RELATION,
                                 h.TEST_RELATION_SCHEMA)
     db.session.commit()
     self.eschema = Schema.create(self.network, Schema.ENTITY,
                                  h.TEST_ENTITY_SCHEMA)
     self.context = ValidationContext(network=self.network)
     entity = deepcopy(TEST_ENTITY)
     entity['network'] = self.network.slug
     entity = validate_entity(entity, self.eschema, self.context)
     entity['title'] = 'Alice'
     a = self.network.Entity.create(self.eschema, entity)
     entity['title'] = 'Bob'
     b = self.network.Entity.create(self.eschema, entity)
     TEST_RELATION['source'] = a.id
     TEST_RELATION['target'] = b.id
     db.session.commit()
Beispiel #26
0
def delete(slug, name):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_manage(project))
    schema = object_or_404(Schema.by_name(project, name))
    deleted = schemata.delete(schema)
    db.session.commit()
    if deleted:
        raise Gone()
    else:
        return jsonify(schema)
Beispiel #27
0
 def setUp(self):
     self.client = h.make_test_app()
     self.network = Network.create({'title': 'Net', 'slug': 'net'})
     self.schema = Schema.create(self.network, Schema.RELATION,
                                 h.TEST_RELATION_SCHEMA)
     db.session.commit()
     self.eschema = Schema.create(self.network, Schema.ENTITY,
                                  h.TEST_ENTITY_SCHEMA)
     self.context = ValidationContext(network=self.network)
     entity = deepcopy(TEST_ENTITY)
     entity['network'] = self.network.slug
     entity = validate_entity(entity, self.eschema, self.context)
     entity['title'] = 'Alice'
     a = self.network.Entity.create(self.eschema, entity)
     entity['title'] = 'Bob'
     b = self.network.Entity.create(self.eschema, entity)
     TEST_RELATION['source'] = a.id
     TEST_RELATION['target'] = b.id
     db.session.commit()
Beispiel #28
0
def delete(slug, name):
    project = object_or_404(Project.by_slug(slug))
    authz.require(authz.project_manage(project))
    schema = object_or_404(Schema.by_name(project, name))
    deleted = schemata.delete(schema)
    db.session.commit()
    if deleted:
        raise Gone()
    else:
        return jsonify(schema)
Beispiel #29
0
def export_schema(project, path):
    if not os.path.exists(path):
        os.makedirs(path)
    for schema in Schema.all().filter_by(project=project):
        fn = os.path.join(path, schema.name + '.yaml')
        with open(fn, 'w') as fh:
            dumped = yaml.safe_dump(schema.to_dict(schema),
                                    canonical=False,
                                    default_flow_style=False,
                                    indent=4)
            fh.write(dumped)
Beispiel #30
0
def export_schema(project, path):
    if not os.path.exists(path):
        os.makedirs(path)
    for schema in Schema.all().filter_by(project=project):
        fn = os.path.join(path, schema.name + '.yaml')
        with open(fn, 'w') as fh:
            dumped = yaml.safe_dump(schema.to_dict(schema),
                                    canonical=False,
                                    default_flow_style=False,
                                    indent=4)
            fh.write(dumped)
Beispiel #31
0
def create(slug, type):
    """ Create a new schema. """
    network = _get_network(slug)
    require.schema.create(network)
    _valid_schema(type)
    data = request_content(request)
    data = validate_schema(dict(data.items()))
    schema = Schema.create(network, type, data)
    db.session.commit()
    url = url_for('.get', slug=network.slug,
            type=schema.entity, name=schema.name)
    return jsonify(schema, status=201, headers={'location': url})
Beispiel #32
0
def import_schema(project, fh):
    data = yaml.load(fh.read())
    if isinstance(data, dict):
        data = [data]
    try:
        for cur in data:
            schema = Schema.by_name(project, cur.get('name'))
            cur['project'] = project
            save(cur, schema=schema)
        db.session.commit()
    except Invalid, inv:
        pprint(inv.asdict())
Beispiel #33
0
def import_schema(project, fh):
    data = yaml.load(fh.read())
    if isinstance(data, dict):
        data = [data]
    try:
        for cur in data:
            schema = Schema.by_name(project, cur.get('name'))
            cur['project'] = project
            save(cur, schema=schema)
        db.session.commit()
    except Invalid, inv:
        pprint(inv.asdict())
Beispiel #34
0
def create(slug, type):
    """ Create a new schema. """
    network = _get_network(slug)
    require.schema.create(network)
    _valid_schema(type)
    data = request_content(request)
    data = validate_schema(dict(data.items()))
    schema = Schema.create(network, type, data)
    db.session.commit()
    url = url_for('.get',
                  slug=network.slug,
                  type=schema.entity,
                  name=schema.name)
    return jsonify(schema, status=201, headers={'location': url})
Beispiel #35
0
def apply_alias(project, author, canonical_name, alias_name):
    """ Given two names, find out if there are existing entities for one or 
    both of them. If so, merge them into a single entity - or, if only the 
    entity associated with the alias exists - re-name the entity. """

    canonical_name = canonical_name.strip()

    # Don't import meaningless aliases.
    if canonical_name == alias_name or not len(canonical_name):
        return log.info("No alias: %s", canonical_name)

    canonical = Entity.by_name(project, canonical_name)
    alias = Entity.by_name(project, alias_name)
    schema = Schema.by_name(project, 'base')

    # Don't artificially increase entity counts.
    if canonical is None and alias is None:
        return log.info("Neither alias nor canonical exist: %s",
                        canonical_name)

    # Rename an alias to its new, canonical name.
    if canonical is None:
        properties_logic.set(alias,
                             author,
                             'name',
                             schema,
                             canonical_name,
                             active=True,
                             source_url=None)
        _entity_changed.delay(alias.id)
        return log.info("Renamed: %s", alias_name)

    # Already done, thanks.
    if canonical == alias:
        return log.info("Already aliased: %s", canonical_name)

    # Merge two existing entities, declare one as "same_as"
    if canonical is not None and alias is not None:
        _merge_entities(alias, canonical)
        _entity_changed.delay(canonical.id)
        return log.info("Mapped: %s -> %s", alias.id, canonical.id)
Beispiel #36
0
def view(slug, name):
    project = object_or_404(Project.by_slug(slug))
    validate_cache(last_modified=project.updated_at)
    schema = object_or_404(Schema.by_name(project, name))
    return jsonify(schemata.to_rest(schema))
Beispiel #37
0
 def test_apply_schema(self):
     base = mapping('entity')
     schema = Schema.create(self.network, Schema.ENTITY,
                            h.TEST_ENTITY_SCHEMA)
     base = apply_schema(base, schema)
     assert len(base.children) == len(h.TEST_ENTITY_SCHEMA['attributes'])
Beispiel #38
0
def view(slug, name):
    project = object_or_404(Project.by_slug(slug))
    validate_cache(last_modified=project.updated_at)
    schema = object_or_404(Schema.by_name(project, name))
    return jsonify(schemata.to_rest(schema))
Beispiel #39
0
def save(data, schema=None):
    """ Create a schema. """
    data = validate(data)

    operation = 'create' if schema is None else 'update'
    if schema is None:
        schema = Schema()
        schema.name = data.get('name')
        schema.project = data.get('project')

    schema.label = data.get('label')
    schema.obj = data.get('obj')
    schema.hidden = data.get('hidden')
    schema.meta = data.get('meta')
    schema.parent = data.get('parent')

    if schema.name in DEFAULTS.values():
        schema.parent = None
    elif schema.parent is None or schema.is_circular():
        schema.parent = Schema.by_name(schema.project,
                                       DEFAULTS.get(schema.obj))

    schema.project.updated_at = datetime.utcnow()
    db.session.add(schema)

    inherited = [a.name for a in schema.inherited_attributes]
    names = []

    for attribute in data.get('attributes', []):
        if attribute.get('name') in inherited:
            continue
        attribute['schema'] = schema
        attr = attributes.save(attribute)
        schema.local_attributes.append(attr)
        names.append(attr.name)

    for attr in schema.local_attributes:
        if attr.name not in names:
            attributes.delete(attr)

    db.session.flush()
    _schema_changed(schema.project.slug, schema.name, operation)
    return schema
Beispiel #40
0
def apply_alias(project, author, canonical_name, alias_name, source_url=None):
    """ Given two names, find out if there are existing entities for one or
    both of them. If so, merge them into a single entity - or, if only the
    entity associated with the alias exists - re-name the entity. """

    # Don't import meaningless aliases.
    if not len(canonical_name) or not len(alias_name):
        return log.info("Not an alias: %s", canonical_name)

    canonical = None

    # de-duplicate existing entities with the same name.
    known_names = set()
    for existing in Entity.by_name_many(project, canonical_name):

        for prop in existing.properties:
            if prop.name != 'name':
                continue
            known_names.add(prop.value)

            # make sure the canonical name is actually active
            # TODO: is this desirable?
            if prop.value == canonical_name:
                prop.active = True
            else:
                prop.active = False

        if canonical is not None and canonical.id != existing.id:
            canonical = merge(existing, canonical)
        else:
            canonical = existing

    schema = Schema.by_name(project, 'base')
    attribute = schema.get_attribute('name')

    # Find aliases, i.e. entities with the alias name which are not
    # the canonical entity.
    q = Entity.by_name_many(project, alias_name)
    if canonical is not None:
        q = q.filter(Entity.id != canonical.id)
    aliases = q.all()

    # If there are no existing aliases with that name, add the alias
    # name to the canonical entity.
    if not len(aliases) and canonical is not None:
        if alias_name not in known_names:
            data = {
                'value': alias_name,
                'schema': schema,
                'attribute': attribute,
                'active': False,
                'name': 'name',
                'source_url': source_url
            }
            properties_logic.save(canonical, data)
            _entity_changed.delay(canonical.id, 'update')
        log.info("Alias: %s -> %s", alias_name, canonical_name)

    for alias in aliases:
        if canonical is None:
            # Rename an alias to its new, canonical name.
            data = {
                'value': canonical_name,
                'schema': schema,
                'attribute': attribute,
                'active': True,
                'name': 'name',
                'source_url': source_url
            }
            properties_logic.save(alias, data)
            _entity_changed.delay(alias.id, 'update')
            log.info("Renamed: %s -> %s", alias_name, canonical_name)
        else:
            # Merge two existing entities, declare one as "same_as"
            merge(alias, canonical)
            log.info("Mapped: %s -> %s", alias.id, canonical.id)

    db.session.commit()
Beispiel #41
0
def save(data, schema=None):
    """ Create a schema. """
    data = validate(data)

    operation = 'create' if schema is None else 'update'
    if schema is None:
        schema = Schema()
        schema.name = data.get('name')
        schema.project = data.get('project')

    schema.label = data.get('label')
    schema.obj = data.get('obj')
    schema.hidden = data.get('hidden')
    schema.meta = data.get('meta')
    schema.parent = data.get('parent')

    if schema.name in DEFAULTS.values():
        schema.parent = None
    elif schema.parent is None or schema.is_circular():
        schema.parent = Schema.by_name(schema.project,
                                       DEFAULTS.get(schema.obj))

    schema.project.updated_at = datetime.utcnow()
    db.session.add(schema)

    inherited = [a.name for a in schema.inherited_attributes]
    names = []

    for attribute in data.get('attributes', []):
        if attribute.get('name') in inherited:
            continue
        attribute['schema'] = schema
        attr = attributes.save(attribute)
        schema.local_attributes.append(attr)
        names.append(attr.name)
    
    for attr in schema.local_attributes:
        if attr.name not in names:
            attributes.delete(attr)

    db.session.flush()
    _schema_changed(schema.project.slug, schema.name, operation)
    return schema
Beispiel #42
0
def apply_alias(project, author, canonical_name, alias_name, source_url=None):
    """ Given two names, find out if there are existing entities for one or
    both of them. If so, merge them into a single entity - or, if only the
    entity associated with the alias exists - re-name the entity. """

    # Don't import meaningless aliases.
    if not len(canonical_name) or not len(alias_name):
        return log.info("Not an alias: %s", canonical_name)

    canonical = None

    # de-duplicate existing entities with the same name.
    known_names = set()
    for existing in Entity.by_name_many(project, canonical_name):

        for prop in existing.properties:
            if prop.name != 'name':
                continue
            known_names.add(prop.value)

            # make sure the canonical name is actually active
            # TODO: is this desirable?
            if prop.value == canonical_name:
                prop.active = True
            else:
                prop.active = False

        if canonical is not None and canonical.id != existing.id:
            canonical = merge(existing, canonical)
        else:
            canonical = existing

    schema = Schema.by_name(project, ENTITY_DEFAULT_SCHEMA)
    attribute = schema.get_attribute('name')

    # Find aliases, i.e. entities with the alias name which are not
    # the canonical entity.
    q = Entity.by_name_many(project, alias_name)
    if canonical is not None:
        q = q.filter(Entity.id != canonical.id)
    aliases = q.all()

    # If there are no existing aliases with that name, add the alias
    # name to the canonical entity.
    if not len(aliases) and canonical is not None:
        if alias_name not in known_names:
            data = {
                'value': alias_name,
                'schema': schema,
                'attribute': attribute,
                'active': False,
                'name': 'name',
                'source_url': source_url
            }
            properties_logic.save(canonical, data)
            _entity_changed.delay(canonical.id, 'update')
        log.info("Alias: %s -> %s", alias_name, canonical_name)

    for alias in aliases:
        if canonical is None:
            # Rename an alias to its new, canonical name.
            data = {
                'value': canonical_name,
                'schema': schema,
                'attribute': attribute,
                'active': True,
                'name': 'name',
                'source_url': source_url
            }
            properties_logic.save(alias, data)
            _entity_changed.delay(alias.id, 'update')
            log.info("Renamed: %s -> %s", alias_name, canonical_name)
        else:
            # Merge two existing entities, declare one as "same_as"
            merge(alias, canonical)
            log.info("Mapped: %s -> %s", alias.id, canonical.id)

    db.session.commit()
 def test_apply_schema(self):
     base = mapping('entity')
     schema = Schema.create(self.network, Schema.ENTITY, h.TEST_ENTITY_SCHEMA)
     base = apply_schema(base, schema)
     assert len(base.children)==len(h.TEST_ENTITY_SCHEMA['attributes'])