def test_node(self): with app.app_context(): self.login() with app.test_request_context(): app.preprocess_request() actor_node = NodeMapper.get_hierarchy_by_name('Actor Actor Relation') sex_node = NodeMapper.get_hierarchy_by_name('Sex') rv = self.app.get(url_for('node_index')) assert b'Actor Actor Relation' in rv.data rv = self.app.get(url_for('node_insert', root_id=actor_node.id, super_id=actor_node.id)) assert b'Actor Actor Relation' in rv.data rv = self.app.post( url_for('node_insert', root_id=actor_node.id), data={'name_search': 'new'}) assert b'Inverse' in rv.data data = { 'name': 'My secret node', 'name_inverse': 'Do I look inverse?', 'description': 'Very important!'} rv = self.app.post(url_for('node_insert', root_id=actor_node.id), data=data) node_id = rv.location.split('/')[-1].replace('node#tab-', '') rv = self.app.get(url_for('node_update', id_=node_id)) assert b'My secret node' in rv.data and b'Super' in rv.data self.app.post(url_for('node_insert', root_id=sex_node.id), data=data) rv = self.app.post( url_for('node_update', id_=node_id), data=data, follow_redirects=True) assert b'Changes have been saved.' in rv.data # Test insert an continue data['continue_'] = 'yes' rv = self.app.post( url_for('node_insert', root_id=actor_node.id), data=data, follow_redirects=True) assert b'An entry has been created' in rv.data data['continue_'] = '' # Test forbidden system node rv = self.app.post( url_for('node_update', id_=actor_node.id), data=data, follow_redirects=True) assert b'Forbidden' in rv.data # Test update with self as root data[str(actor_node.id)] = node_id rv = self.app.post( url_for('node_update', id_=node_id), data=data, follow_redirects=True) assert b'Type can't have itself as super.' in rv.data # Test update with a child as root rv = self.app.post(url_for('node_insert', root_id=actor_node.id), data=data) child_node_id = rv.location.split('/')[-1].replace('node#tab-', '') data[str(actor_node.id)] = child_node_id rv = self.app.post( url_for('node_update', id_=node_id), data=data, follow_redirects=True) assert b'Type can't have a sub as super.' in rv.data # Test delete system node rv = self.app.get(url_for('node_delete', id_=actor_node.id), follow_redirects=True) assert b'Forbidden' in rv.data rv = self.app.get(url_for('node_delete', id_=child_node_id), follow_redirects=True) assert b'The entry has been deleted.' in rv.data
def test_hierarchy(self): with app.app_context(): self.login() rv = self.app.get(url_for('hierarchy_insert', param='custom')) assert b'+ Custom' in rv.data data = {'name': 'Geronimo', 'multiple': True, 'description': 'Very important!'} rv = self.app.post(url_for('hierarchy_insert', param='custom'), data=data) hierarchy_id = rv.location.split('/')[-1].replace('types#tab-', '') rv = self.app.get(url_for('hierarchy_update', id_=hierarchy_id)) assert b'Geronimo' in rv.data rv = self.app.post( url_for('hierarchy_update', id_=hierarchy_id), data=data, follow_redirects=True) assert b'Changes have been saved.' in rv.data data['name'] = 'Actor Actor Relation' rv = self.app.post( url_for('hierarchy_update', id_=hierarchy_id), data=data, follow_redirects=True) assert b'The name is already in use' in rv.data rv = self.app.post(url_for('hierarchy_delete', id_=hierarchy_id), follow_redirects=True) assert b'deleted' in rv.data # Test checks actor_node = NodeMapper.get_hierarchy_by_name('Actor Actor Relation') rv = self.app.get(url_for('hierarchy_update', id_=actor_node.id), follow_redirects=True) assert b'Forbidden' in rv.data rv = self.app.get(url_for('hierarchy_delete', id_=actor_node.id), follow_redirects=True) assert b'Forbidden' in rv.data rv = self.app.post(url_for('hierarchy_insert', param='custom'), data=data) assert b'The name is already in use' in rv.data
def test_hierarchy(self): with app.app_context(): self.login() # Custom types data = { 'name': 'Geronimo', 'forms': [1, 2, 4, 5, 6], 'multiple': True, 'description': 'Very important!'} rv = self.app.post(url_for('hierarchy_insert', param='custom'), data=data) hierarchy_id = rv.location.split('/')[-1].replace('types#tab-', '') rv = self.app.get(url_for('hierarchy_update', id_=hierarchy_id)) assert b'Geronimo' in rv.data data['forms'] = [3] rv = self.app.post( url_for('hierarchy_update', id_=hierarchy_id), data=data, follow_redirects=True) assert b'Changes have been saved.' in rv.data rv = self.app.get(url_for('hierarchy_insert', param='custom')) assert b'+ Custom' in rv.data data = {'name': 'My secret node', 'description': 'Very important!'} rv = self.app.post(url_for('node_insert', root_id=hierarchy_id), data=data) node_id = rv.location.split('/')[-1].replace('types#tab-', '') rv = self.app.get(url_for('hierarchy_remove_form', id_=hierarchy_id, remove_id=2), follow_redirects=True) assert b'Changes have been saved.' in rv.data self.app.get(url_for('node_delete', id_=node_id)) data['name'] = 'Actor Actor Relation' rv = self.app.post( url_for('hierarchy_update', id_=hierarchy_id), data=data, follow_redirects=True) assert b'The name is already in use' in rv.data rv = self.app.post(url_for('hierarchy_delete', id_=hierarchy_id), follow_redirects=True) assert b'deleted' in rv.data # Value types rv = self.app.get(url_for('hierarchy_insert', param='value')) assert b'+ Value' in rv.data data2 = {'name': 'A valued value type', 'forms': [1], 'description': ''} rv = self.app.post(url_for('hierarchy_insert', param='value'), data=data2) custom_hierarchy_id = rv.location.split('/')[-1].replace('types#tab-', '') rv = self.app.get(url_for('hierarchy_update', id_=custom_hierarchy_id)) assert b'valued' in rv.data # Test checks actor_node = NodeMapper.get_hierarchy_by_name('Actor Actor Relation') rv = self.app.get(url_for('hierarchy_update', id_=actor_node.id), follow_redirects=True) assert b'Forbidden' in rv.data rv = self.app.get(url_for('hierarchy_delete', id_=actor_node.id), follow_redirects=True) assert b'Forbidden' in rv.data rv = self.app.post(url_for('hierarchy_insert', param='custom'), data=data) assert b'The name is already in use' in rv.data
def test_involvement(self): with app.app_context(): self.login() with app.test_request_context(): app.preprocess_request() actor_id = EntityMapper.insert('E21', 'Captain Miller').id event_id = EntityMapper.insert('E8', 'Event Horizon').id involvement_id = NodeMapper.get_hierarchy_by_name( 'Involvement').id # add involvement rv = self.app.get(url_for('involvement_insert', origin_id=actor_id)) assert b'Involvement' in rv.data data = { 'event': '[' + str(event_id) + ']', 'activity': 'P11', involvement_id: involvement_id } rv = self.app.post(url_for('involvement_insert', origin_id=actor_id), data=data, follow_redirects=True) assert b'Event Horizon' in rv.data data = { 'actor': '[' + str(actor_id) + ']', 'continue_': 'yes', 'activity': 'P22' } rv = self.app.post(url_for('involvement_insert', origin_id=event_id), data=data, follow_redirects=True) assert b'Event Horizon' in rv.data self.app.get(url_for('event_view', id_=event_id)) # update involvement with app.test_request_context(): app.preprocess_request() link_id = LinkMapper.get_links(event_id, 'P22')[0].id rv = self.app.get( url_for('involvement_update', id_=link_id, origin_id=event_id)) assert b'Captain' in rv.data rv = self.app.post(url_for('involvement_update', id_=link_id, origin_id=actor_id), data={ 'description': 'Infinite Space - Infinite Terror', 'activity': 'P23' }, follow_redirects=True) assert b'Infinite Space - Infinite Terror' in rv.data self.app.get(url_for('event_view', id_=event_id))
def test_node(self): with app.app_context(): self.login() with app.test_request_context(): app.preprocess_request() actor_node = NodeMapper.get_hierarchy_by_name('Actor Actor Relation') sex_node = NodeMapper.get_hierarchy_by_name('Sex') rv = self.app.get(url_for('node_index')) assert b'Actor Actor Relation' in rv.data rv = self.app.post( url_for('node_insert', root_id=actor_node.id), data={'name_search': 'new'}) assert b'Inverse' in rv.data data = { 'name': 'My secret node', 'name_inverse': 'Do I look inverse?', 'description': 'Very important!'} rv = self.app.post(url_for('node_insert', root_id=actor_node.id), data=data) node_id = rv.location.split('/')[-1].replace('node#tab-', '') rv = self.app.get(url_for('node_update', id_=node_id)) assert b'My secret node' in rv.data and b'Super' in rv.data self.app.post(url_for('node_insert', root_id=sex_node.id), data=data) rv = self.app.post( url_for('node_update', id_=node_id), data=data, follow_redirects=True) assert b'Changes have been saved.' in rv.data # Test forbidden system node rv = self.app.post( url_for('node_update', id_=actor_node.id), data=data, follow_redirects=True) assert b'Forbidden' in rv.data # Test update with self as root data[str(actor_node.id)] = node_id rv = self.app.post( url_for('node_update', id_=node_id), data=data, follow_redirects=True) assert b'super' in rv.data # Test delete system node rv = self.app.get(url_for('node_delete', id_=actor_node.id), follow_redirects=True) assert b'Forbidden' in rv.data rv = self.app.get(url_for('node_delete', id_=node_id), follow_redirects=True) assert b'The entry has been deleted.' in rv.data
def __call__(self, field, **kwargs): from openatlas.models.node import NodeMapper selection = '' selected_ids = [] if field.data: field.data = field.data[0] if isinstance(field.data, list) else field.data selection = g.nodes[int(field.data)].name selected_ids.append(g.nodes[int(field.data)].id) try: hierarchy_id = int(field.id) except ValueError: hierarchy_id = NodeMapper.get_hierarchy_by_name(uc_first(field.id)).id root = g.nodes[hierarchy_id] html = """ <input id="{name}-button" name="{name}-button" type="text" class="table-select {required}" onfocus="this.blur()" readonly="readonly" value="{selection}" placeholder="{change_label}" /> <a id="{name}-clear" {clear_style} class="button" onclick="clearSelect('{name}');">{clear_label}</a> <div id="{name}-overlay" class="overlay"> <div id="{name}-dialog" class="overlay-container"> <input class="tree-filter" id="{name}-tree-search" placeholder="Filter" /> <div id="{name}-tree"></div> </div> </div> <script> $(document).ready(function () {{ createOverlay("{name}","{title}",false,); $("#{name}-tree").jstree({{ "core" : {{"check_callback" : true, 'data':[{tree_data}]}}, "search": {{"case_insensitive": true, "show_only_matches": true}}, "plugins" : ["search"], }}); $("#{name}-tree").on("select_node.jstree", function (e, data) {{ selectFromTree("{name}", data.node.id, data.node.text); }}); $("#{name}-tree-search").keyup(function() {{ $("#{name}-tree").jstree("search", $(this).val()); }}); }}); </script>""".format( name=field.id, title=root.name, change_label=uc_first(_('change')), clear_label=uc_first(_('clear')), selection=selection, tree_data=NodeMapper.get_tree_data(hierarchy_id, selected_ids), clear_style='' if selection else ' style="display: none;" ', required=' required' if field.flags.required else '') return super(TreeSelect, self).__call__(field, **kwargs) + html
def print_base_type(self): from openatlas.models.node import NodeMapper if not self.view_name or self.view_name == 'actor': # actors have no base type return '' root_name = self.view_name.title() if self.view_name == 'reference': root_name = self.system_type.title() elif self.view_name == 'file': root_name = 'License' elif self.view_name == 'place': root_name = uc_first(self.system_type) if self.system_type == 'stratigraphic unit': root_name = 'Stratigraphic Unit' root_id = NodeMapper.get_hierarchy_by_name(root_name).id for node in self.nodes: if node.root and node.root[-1] == root_id: return node.name return ''
def print_base_type(self): from openatlas.models.node import NodeMapper view_name = get_view_name(self) if not view_name or view_name == 'actor': # actors have no base type return '' root_name = view_name.title() if view_name == 'reference': root_name = self.system_type.title() elif view_name == 'file': root_name = 'License' elif view_name == 'place': root_name = uc_first(self.system_type) if self.system_type == 'stratigraphic unit': root_name = 'Stratigraphic Unit' root_id = NodeMapper.get_hierarchy_by_name(root_name).id for node in self.nodes: if node.root and node.root[-1] == root_id: return node.name return ''
def test_involvement(self): with app.app_context(): self.login() rv = self.app.post(url_for('event_insert', code='E8'), data={ 'name': 'Event Horizon', 'date_begin_year': '1949', 'date_begin_month': '10', 'date_begin_day': '8', 'date_end_year': '1951'}) event_id = int(rv.location.split('/')[-1]) with app.test_request_context(): app.preprocess_request() actor_id = EntityMapper.insert('E21', 'Captain Miller').id involvement_id = NodeMapper.get_hierarchy_by_name('Involvement').id # Add involvement rv = self.app.get(url_for('involvement_insert', origin_id=actor_id)) assert b'Involvement' in rv.data data = {'event': '[' + str(event_id) + ']', 'activity': 'P11', involvement_id: involvement_id} rv = self.app.post(url_for('involvement_insert', origin_id=actor_id), data=data, follow_redirects=True) assert b'Event Horizon' in rv.data data = {'actor': '[' + str(actor_id) + ']', 'continue_': 'yes', 'activity': 'P22'} rv = self.app.post(url_for('involvement_insert', origin_id=event_id), data=data, follow_redirects=True) assert b'Event Horizon' in rv.data self.app.get(url_for('event_view', id_=event_id)) # Update involvement with app.test_request_context(): app.preprocess_request() link_id = LinkMapper.get_links(event_id, 'P22')[0].id rv = self.app.get(url_for('involvement_update', id_=link_id, origin_id=event_id)) assert b'Captain' in rv.data rv = self.app.post( url_for('involvement_update', id_=link_id, origin_id=actor_id), data={'description': 'Infinite Space - Infinite Terror', 'activity': 'P23'}, follow_redirects=True) assert b'Infinite Space - Infinite Terror' in rv.data self.app.get(url_for('event_view', id_=event_id))
def print_base_type(self) -> str: from openatlas.models.node import NodeMapper if not self.view_name or self.view_name == 'actor': # actors have no base type return '' root_name = self.view_name.title() if self.view_name == 'reference': root_name = self.system_type.title() if root_name == 'External Reference Geonames': root_name = 'External Reference' elif self.view_name == 'file': root_name = 'License' elif self.view_name == 'place': root_name = uc_first(self.system_type) if self.system_type == 'stratigraphic unit': root_name = 'Stratigraphic Unit' elif self.class_.code == 'E84': root_name = 'Information Carrier' root_id = NodeMapper.get_hierarchy_by_name(root_name).id for node in self.nodes: if node.root and node.root[-1] == root_id: return node.name return ''
def get_all(object_ids=None): all_ = {'point': [], 'polygon': []} selected = {'point': [], 'polygon': [], 'polygon_point': []} object_ids = object_ids if object_ids else [] object_ids = object_ids if isinstance(object_ids, list) else [object_ids] polygon_point_sql = """ (SELECT public.ST_AsGeoJSON(public.ST_PointOnSurface(p.geom)) FROM gis.polygon p WHERE id = polygon.id) AS polygon_point, """ for shape in ['point', 'polygon']: sql = """ SELECT object.id AS object_id, {shape}.id, {shape}.name, {shape}.description, {shape}.type, public.ST_AsGeoJSON({shape}.geom) AS geojson, {polygon_point_sql} object.name AS object_name, object.description AS object_desc, object.system_type AS object_system_type, string_agg(CAST(t.range_id AS text), ',') AS types, (SELECT COUNT(*) FROM gis.point point2 WHERE {shape}.entity_id = point2.entity_id) AS point_count, (SELECT COUNT(*) FROM gis.polygon polygon2 WHERE {shape}.entity_id = polygon2.entity_id) AS polygon_count FROM model.entity place JOIN model.link l ON place.id = l.range_id JOIN model.entity object ON l.domain_id = object.id JOIN gis.{shape} {shape} ON place.id = {shape}.entity_id LEFT JOIN model.link t ON object.id = t.domain_id AND t.property_code = 'P2' WHERE place.class_code = 'E53' AND l.property_code = 'P53' AND object.system_type = 'place' GROUP BY object.id, {shape}.id;""".format( shape=shape, polygon_point_sql=polygon_point_sql if shape == 'polygon' else '') g.cursor.execute(sql) place_type_root_id = NodeMapper.get_hierarchy_by_name('Place').id for row in g.cursor.fetchall(): description = row.description.replace('"', '\"') if row.description else '' object_desc = row.object_desc.replace('"', '\"') if row.object_desc else '' item = { 'type': 'Feature', 'geometry': json.loads(row.geojson), 'properties': { 'title': row.object_name.replace('"', '\"'), 'objectId': row.object_id, 'objectDescription': object_desc, 'id': row.id, 'name': row.name.replace('"', '\"'), 'description': description, 'siteType': '', 'shapeType': uc_first(row.type), 'count': row.point_count + row.polygon_count}} if hasattr(row, 'types') and row.types: nodes_list = ast.literal_eval('[' + row.types + ']') for node_id in list(set(nodes_list)): node = g.nodes[node_id] if node.root and node.root[-1] == place_type_root_id: item['properties']['siteType'] = node.name break if row.object_id in object_ids: selected[shape].append(item) elif row.object_system_type != 'place': continue else: all_[shape].append(item) if hasattr(row, 'polygon_point'): polygon_point_item = dict(item) # make a copy to prevent overriding geometry polygon_point_item['geometry'] = json.loads(row.polygon_point) if row.object_id in object_ids: selected['polygon_point'].append(polygon_point_item) elif row.object_system_type != 'place': continue else: all_['point'].append(polygon_point_item) gis = { 'gisPointAll': json.dumps(all_['point']), 'gisPointSelected': json.dumps(selected['point']), 'gisPolygonAll': json.dumps(all_['polygon']), 'gisPolygonSelected': json.dumps(selected['polygon']), 'gisPolygonPointSelected': json.dumps(selected['polygon_point'])} return gis
def test_place(self): with app.app_context(): self.login() rv = self.app.get(url_for('place_insert')) assert b'+ Place' in rv.data data = {'name': 'Asgard', 'alias-0': 'Valhöll'} with app.test_request_context(): app.preprocess_request() reference_id = EntityMapper.insert('E31', 'Ancient Books', 'edition').id place_node = NodeMapper.get_hierarchy_by_name('Place') source_id = EntityMapper.insert('E33', 'Tha source').id rv = self.app.post(url_for('place_insert', origin_id=reference_id), data=data, follow_redirects=True) assert b'Asgard' in rv.data gis_points = """[{"type":"Feature", "geometry":{"type":"Point", "coordinates":[9,17]}, "properties":{"name":"Valhalla","description":"","shapeType":"centerpoint"}}]""" data['gis_points'] = gis_points gis_polygons = """[{"geometry":{ "coordinates":[[[9.75307425847859,17.8111792731339], [9.75315472474904,17.8110005175436],[9.75333711496205,17.8110873417098], [9.75307425847859,17.8111792731339]]],"type":"Polygon"}, "properties":{"count":4,"description":"","id":8,"name":"", "objectDescription":"","objectId":185,"shapeType":"Shape", "siteType":"Settlement","title":""},"type":"Feature"}]""" data['gis_polygons'] = gis_polygons data[place_node.id] = place_node.subs data['continue_'] = 'yes' rv = self.app.post( url_for('place_insert', origin_id=source_id), data=data, follow_redirects=True) assert b'Tha source' in rv.data with app.test_request_context(): app.preprocess_request() places = EntityMapper.get_by_codes('place') place_id = places[0].id second_place_id = places[1].id location = LinkMapper.get_linked_entity(second_place_id, 'P53') actor_id = EntityMapper.insert('E21', 'Milla Jovovich').id LinkMapper.insert(actor_id, 'P74', location.id) assert b'Tha source' in rv.data rv = self.app.get(url_for('place_index')) assert b'Asgard' in rv.data rv = self.app.get(url_for('place_update', id_=place_id)) assert b'Valhalla' in rv.data data['continue_'] = '' data['alias-1'] = 'Val-hall' rv = self.app.post( url_for('place_update', id_=place_id), data=data, follow_redirects=True) assert b'Val-hall' in rv.data with app.test_request_context(): app.preprocess_request() event = EntityMapper.insert('E8', 'Valhalla rising') event.link('P7', location) event.link('P24', location) rv = self.app.get( url_for( 'place_view', id_=second_place_id, unlink_id=place_id), follow_redirects=True) assert b'Link removed' in rv.data and b'Milla Jovovich' in rv.data # Subunits with app.app_context(): self.app.get(url_for('place_insert', origin_id=place_id)) name = "It's not a bug, it's a feature!" rv = self.app.post(url_for('place_insert', origin_id=place_id), data={'name': name}) feat_id = rv.location.split('/')[-1] self.app.get(url_for('place_insert', origin_id=feat_id)) self.app.get(url_for('place_update', id_=feat_id)) self.app.post(url_for('place_update', id_=feat_id), data={'name': name}) name = "I'm a stratigraphic unit" rv = self.app.post(url_for('place_insert', origin_id=feat_id), data={'name': name}) strat_id = rv.location.split('/')[-1] self.app.get(url_for('place_insert', origin_id=strat_id)) self.app.get(url_for('place_update', id_=strat_id)) self.app.post(url_for('place_update', id_=strat_id), data={'name': name}) name = "You never find me" rv = self.app.post(url_for('place_insert', origin_id=strat_id), data={'name': name}) find_id = rv.location.split('/')[-1] self.app.get(url_for('place_update', id_=find_id)) self.app.post(url_for('place_update', id_=find_id), data={'name': name}) rv = self.app.get(url_for('place_view', id_=feat_id)) assert b'not a bug' in rv.data rv = self.app.get(url_for('place_view', id_=strat_id)) assert b'a stratigraphic unit' in rv.data rv = self.app.get(url_for('place_view', id_=find_id)) assert b'You never' in rv.data rv = self.app.get(url_for('place_delete', id_=place_id), follow_redirects=True) assert b'not possible if subunits' in rv.data rv = self.app.get(url_for('place_delete', id_=find_id), follow_redirects=True) assert b'The entry has been deleted.' in rv.data
def update_geonames(form: FlaskForm, object_: Entity) -> None: new_geonames_id = form.geonames_id.data geonames_link = GeonamesMapper.get_geonames_link(object_) geonames_entity = geonames_link.domain if geonames_link else None if not new_geonames_id: if geonames_entity: if len(geonames_entity.get_links(['P67' ])) > 1: # pragma: no cover if geonames_link: geonames_link.delete( ) # There are more linked so only remove this link else: geonames_entity.delete( ) # Nothing else is linked to the reference so delete it return # Get id of the match type match_id = None for node_id in NodeMapper.get_hierarchy_by_name( 'External Reference Match').subs: if g.nodes[ node_id].name == 'exact match' and form.geonames_precision.data: match_id = node_id break if g.nodes[ node_id].name == 'close match' and not form.geonames_precision.data: match_id = node_id break # There wasn't one linked before if not geonames_entity: reference = EntityMapper.get_by_name_and_system_type( new_geonames_id, 'external reference geonames') if not reference: # The selected reference doesn't exist so create it reference = EntityMapper.insert('E31', new_geonames_id, 'external reference geonames', description='GeoNames ID') object_.link('P67', reference, inverse=True, type_id=match_id) return if geonames_link and int(new_geonames_id) == int(geonames_entity.name) \ and match_id == geonames_link.type.id: return # It's the same link so do nothing # Only the match type change so delete and recreate the link if geonames_link and int(new_geonames_id) == int(geonames_entity.name): geonames_link.delete() object_.link('P67', geonames_entity, inverse=True, type_id=match_id) return # Its linked to a different geonames reference if geonames_link and len(geonames_entity.get_links(['P67'])) > 1: geonames_link.delete( ) # There are more linked so only remove this link else: # pragma: no cover geonames_entity.delete( ) # Nothing else is linked to the reference so delete it reference = EntityMapper.get_by_name_and_system_type( new_geonames_id, 'external reference geonames') if not reference: # The selected reference doesn't exist so create it reference = EntityMapper.insert('E31', new_geonames_id, 'external reference geonames', description='GeoNames ID') object_.link('P67', reference, inverse=True, type_id=match_id)
def test_relation(self): with app.app_context(): self.login() with app.test_request_context(): app.preprocess_request() actor_id = EntityMapper.insert('E21', 'Connor MacLeod').id related_id = EntityMapper.insert('E21', 'The Kurgan').id # Add relationship rv = self.app.get(url_for('relation_insert', origin_id=actor_id)) assert b'Actor Actor Relation' in rv.data relation_id = NodeMapper.get_hierarchy_by_name('Actor Actor Relation').id relation_sub_id = g.nodes[relation_id].subs[0] data = { 'actor': '[' + str(related_id) + ']', relation_id: relation_sub_id, 'inverse': None, 'date_begin_year': '-1949', 'date_begin_month': '10', 'date_begin_day': '8', 'date_begin_year2': '-1948', 'date_end_year': '2049', 'date_end_year2': '2050'} rv = self.app.post( url_for('relation_insert', origin_id=actor_id), data=data, follow_redirects=True) assert b'The Kurgan' in rv.data rv = self.app.get(url_for('node_view', id_=relation_sub_id)) assert b'Connor' in rv.data data['continue_'] = 'yes' data['inverse'] = True rv = self.app.post( url_for('relation_insert', origin_id=actor_id), data=data, follow_redirects=True) assert b'The Kurgan' in rv.data rv = self.app.get(url_for('actor_view', id_=actor_id)) assert b'The Kurgan' in rv.data rv = self.app.post( url_for('relation_insert', origin_id=related_id), data=data, follow_redirects=True) assert b"Can't link to itself." in rv.data # Relation types rv = self.app.get(url_for('node_move_entities', id_=relation_sub_id)) assert b'The Kurgan' in rv.data # Update relationship with app.test_request_context(): app.preprocess_request() link_id = LinkMapper.get_links(actor_id, 'OA7')[0].id link_id2 = LinkMapper.get_links(actor_id, 'OA7', True)[0].id rv = self.app.get(url_for('relation_update', id_=link_id, origin_id=related_id)) assert b'Connor' in rv.data rv = self.app.post( url_for('relation_update', id_=link_id, origin_id=actor_id), data={'description': 'There can be only one!', 'inverse': True}, follow_redirects=True) assert b'only one' in rv.data rv = self.app.post( url_for('relation_update', id_=link_id2, origin_id=actor_id), data={'description': 'There can be only one!', 'inverse': None}, follow_redirects=True) assert b'only one' in rv.data
def get_all(objects=None): all_ = {'point': [], 'linestring': [], 'polygon': []} selected = {'point': [], 'linestring': [], 'polygon': [], 'polygon_point': []} # Workaround to include GIS features of a subunit which would be otherwise omitted subunit_selected_id = 0 if objects: if type(objects) is not list: if objects.system_type in ['feature', 'finds', 'stratigraphic unit']: subunit_selected_id = objects.id objects = [objects] else: objects = [] object_ids = [x.id for x in objects] polygon_point_sql = \ 'public.ST_AsGeoJSON(public.ST_PointOnSurface(polygon.geom)) AS polygon_point, ' for shape in ['point', 'polygon', 'linestring']: sql = """ SELECT object.id AS object_id, {shape}.id, {shape}.name, {shape}.description, {shape}.type, public.ST_AsGeoJSON({shape}.geom) AS geojson, {polygon_point_sql} object.name AS object_name, object.description AS object_desc, string_agg(CAST(t.range_id AS text), ',') AS types FROM model.entity place JOIN model.link l ON place.id = l.range_id JOIN model.entity object ON l.domain_id = object.id JOIN gis.{shape} {shape} ON place.id = {shape}.entity_id LEFT JOIN model.link t ON object.id = t.domain_id AND t.property_code = 'P2' WHERE place.class_code = 'E53' AND l.property_code = 'P53' AND (object.system_type = 'place' OR object.id = {subunit_selected_id}) GROUP BY object.id, {shape}.id;""".format( shape=shape, subunit_selected_id=subunit_selected_id, polygon_point_sql=polygon_point_sql if shape == 'polygon' else '') g.cursor.execute(sql) debug_model['div sql'] += 1 place_type_root_id = NodeMapper.get_hierarchy_by_name('Place').id for row in g.cursor.fetchall(): description = row.description.replace('"', '\"') if row.description else '' object_desc = row.object_desc.replace('"', '\"') if row.object_desc else '' item = {'type': 'Feature', 'geometry': json.loads(row.geojson), 'properties': { 'objectId': row.object_id, 'objectName': row.object_name.replace('"', '\"'), 'objectDescription': object_desc, 'id': row.id, 'name': row.name.replace('"', '\"') if row.name else '', 'description': description, 'shapeType': row.type}} if hasattr(row, 'types') and row.types: nodes_list = ast.literal_eval('[' + row.types + ']') for node_id in list(set(nodes_list)): node = g.nodes[node_id] if node.root and node.root[-1] == place_type_root_id: item['properties']['objectType'] = node.name.replace('"', '\"') break if row.object_id in object_ids: selected[shape].append(item) else: all_[shape].append(item) if hasattr(row, 'polygon_point'): polygon_point_item = dict(item) # make a copy to prevent overriding geometry polygon_point_item['geometry'] = json.loads(row.polygon_point) if row.object_id in object_ids: selected['polygon_point'].append(polygon_point_item) else: all_['point'].append(polygon_point_item) return {'gisPointAll': json.dumps(all_['point']), 'gisPointSelected': json.dumps(selected['point']), 'gisLineAll': json.dumps(all_['linestring']), 'gisLineSelected': json.dumps(selected['linestring']), 'gisPolygonAll': json.dumps(all_['polygon']), 'gisPolygonSelected': json.dumps(selected['polygon']), 'gisPolygonPointSelected': json.dumps(selected['polygon_point'])}
def test_place(self): with app.app_context(): self.login() rv = self.app.get(url_for('place_insert')) assert b'+ Place' in rv.data with app.test_request_context(): app.preprocess_request() unit_node = NodeMapper.get_hierarchy_by_name( 'Administrative Unit') unit_sub1 = g.nodes[unit_node.subs[0]] unit_sub2 = g.nodes[unit_node.subs[1]] reference = EntityMapper.insert('E31', 'https://openatlas.eu', 'external reference') place_node = NodeMapper.get_hierarchy_by_name('Place') source = EntityMapper.insert('E33', 'Necronomicon') data = { 'name': 'Asgard', 'alias-0': 'Valhöll', 'geonames_id': '123', 'geonames_precision': True, unit_node.id: str([unit_sub1.id, unit_sub2.id]) } rv = self.app.post(url_for('place_insert', origin_id=reference.id), data=data, follow_redirects=True) assert b'Asgard' in rv.data data['gis_points'] = """[{ "type":"Feature", "geometry":{"type":"Point","coordinates":[9,17]}, "properties":{"name":"Valhalla","description":"","shapeType":"centerpoint"}}]""" data['gis_lines'] = """[{ "type":"Feature", "geometry":{ "type":"LineString", "coordinates":[[9.75307425847859,17.8111792731339], [9.75315472474904,17.8110005175436],[9.75333711496205,17.8110873417098]]}, "properties":{"name":"","description":"","shapeType":"line"}}]""" data['gis_polygons'] = """[{ "type":"Feature", "geometry":{ "type":"Polygon", "coordinates":[[[9.75307425847859,17.8111792731339], [9.75315472474904,17.8110005175436],[9.75333711496205,17.8110873417098], [9.75307425847859,17.8111792731339]]]}, "properties":{"name":"","description":"","shapeType":"shape"}}]""" data[place_node.id] = place_node.subs data['continue_'] = 'yes' rv = self.app.post(url_for('place_insert', origin_id=source.id), data=data, follow_redirects=True) assert b'Necronomicon' in rv.data with app.test_request_context(): app.preprocess_request() places = EntityMapper.get_by_system_type('place') place = places[0] place2 = places[1] location = place2.get_linked_entity('P53') actor = EntityMapper.insert('E21', 'Milla Jovovich') actor.link('P74', location) assert b'Necronomicon' in rv.data rv = self.app.get(url_for('place_index')) assert b'Asgard' in rv.data rv = self.app.get(url_for('place_update', id_=place.id)) assert b'Valhalla' in rv.data data['continue_'] = '' data['alias-1'] = 'Val-hall' data['geonames_id'] = '321' rv = self.app.post(url_for('place_update', id_=place.id), data=data, follow_redirects=True) assert b'Val-hall' in rv.data # Test with same GeoNames id rv = self.app.post(url_for('place_update', id_=place.id), data=data, follow_redirects=True) assert b'Val-hall' in rv.data # Test with same GeoNames id but different precision data['geonames_precision'] = '' rv = self.app.post(url_for('place_update', id_=place.id), data=data, follow_redirects=True) assert b'Val-hall' in rv.data # Test update without the previous GeoNames id data['geonames_id'] = '' rv = self.app.post(url_for('place_update', id_=place.id), data=data, follow_redirects=True) assert b'Val-hall' in rv.data with app.test_request_context(): app.preprocess_request() event = EntityMapper.insert('E8', 'Valhalla rising') event.link('P7', location) event.link('P24', location) rv = self.app.get(url_for('place_view', id_=place2.id)) assert rv.data and b'Valhalla rising' in rv.data # Test invalid geom data['gis_polygons'] = """[{"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [ [[298.9893436362036, -5.888919049309554], [299.00444983737543, -5.9138487869408545], [299.00650977389887, -5.893358673645309], [298.9848804404028, -5.9070188333813585], [298.9893436362036, -5.888919049309554]]]}, "properties": {"name": "", "description": "", "shapeType": "shape"}}]""" rv = self.app.post(url_for('place_insert', origin_id=source.id), data=data, follow_redirects=True) assert b'An invalid geometry was entered' in rv.data # Test Overlays with open( os.path.dirname(__file__) + '/../static/images/layout/logo.png', 'rb') as img: rv = self.app.post(url_for('file_insert', origin_id=place.id), data={ 'name': 'X-Files', 'file': img }, follow_redirects=True) assert b'An entry has been created' in rv.data with app.test_request_context(): app.preprocess_request() file = EntityMapper.get_by_system_type('file')[0] link_id = LinkMapper.insert(file, 'P67', place.id) rv = self.app.get( url_for('overlay_insert', image_id=file.id, place_id=place.id, link_id=link_id)) assert b'X-Files' in rv.data data = { 'top_left_easting': 42, 'top_left_northing': 12, 'bottom_right_easting': 43, 'bottom_right_northing': 13 } rv = self.app.post(url_for('overlay_insert', image_id=file.id, place_id=place.id, link_id=link_id), data=data, follow_redirects=True) assert b'Edit' in rv.data with app.test_request_context(): app.preprocess_request() overlay = OverlayMapper.get_by_object(place) overlay_id = overlay[list(overlay.keys())[0]].id rv = self.app.get( url_for('overlay_update', id_=overlay_id, place_id=place.id, link_id=link_id)) assert b'42' in rv.data rv = self.app.post(url_for('overlay_update', id_=overlay_id, place_id=place.id, link_id=link_id), data=data, follow_redirects=True) assert b'Changes have been saved' in rv.data self.app.get(url_for('overlay_remove', id_=overlay_id, place_id=place.id), follow_redirects=True) # Add to place rv = self.app.get(url_for('place_add_file', id_=place.id)) assert b'Add File' in rv.data rv = self.app.post(url_for('place_add_file', id_=place.id), data={'checkbox_values': str([file.id])}, follow_redirects=True) assert b'X-Files' in rv.data rv = self.app.get(url_for('place_add_source', id_=place.id)) assert b'Add Source' in rv.data rv = self.app.post(url_for('place_add_source', id_=place.id), data={'checkbox_values': str([source.id])}, follow_redirects=True) assert b'Necronomicon' in rv.data rv = self.app.get(url_for('place_add_reference', id_=place.id)) assert b'Add Reference' in rv.data rv = self.app.post(url_for('place_add_reference', id_=place.id), data={ 'reference': reference.id, 'page': '777' }, follow_redirects=True) assert b'777' in rv.data # Place types rv = self.app.get(url_for('node_move_entities', id_=unit_sub1.id)) assert b'Asgard' in rv.data # Test move entities of multiple node if link to new node exists rv = self.app.post(url_for('node_move_entities', id_=unit_sub1.id), data={ unit_node.id: unit_sub2.id, 'selection': location.id, 'checkbox_values': str([location.id]) }, follow_redirects=True) assert b'Entities where updated' in rv.data # Test move entities of multiple node if link to new node doesn't exists rv = self.app.post(url_for('node_move_entities', id_=unit_sub2.id), data={ unit_node.id: unit_sub1.id, 'selection': location.id, 'checkbox_values': str([location.id]) }, follow_redirects=True) assert b'Entities where updated' in rv.data # Subunits with app.app_context(): self.app.get(url_for('place_insert', origin_id=place.id)) rv = self.app.post( url_for('place_insert', origin_id=place.id), data={'name': "It's not a bug, it's a feature!"}) feat_id = rv.location.split('/')[-1] self.app.get(url_for('place_insert', origin_id=feat_id)) self.app.get(url_for('place_update', id_=feat_id)) self.app.post(url_for('place_update', id_=feat_id), data={'name': "It's not a bug, it's a feature!"}) rv = self.app.post(url_for('place_insert', origin_id=feat_id), data={'name': "I'm a stratigraphic unit"}) stratigraphic_id = rv.location.split('/')[-1] self.app.get( url_for('place_insert', origin_id=stratigraphic_id)) self.app.get(url_for('place_update', id_=stratigraphic_id)) self.app.post(url_for('place_update', id_=stratigraphic_id), data={'name': "I'm a stratigraphic unit"}) dimension_node_id = NodeMapper.get_hierarchy_by_name( 'Dimensions').subs[0] data = { 'name': 'You never find me', str(dimension_node_id): '50' } rv = self.app.post(url_for('place_insert', origin_id=stratigraphic_id), data=data) find_id = rv.location.split('/')[-1] self.app.get(url_for('place_update', id_=find_id)) self.app.post(url_for('place_update', id_=find_id), data=data) rv = self.app.get(url_for('place_view', id_=feat_id)) assert b'not a bug' in rv.data rv = self.app.get(url_for('place_view', id_=stratigraphic_id)) assert b'a stratigraphic unit' in rv.data rv = self.app.get(url_for('place_view', id_=find_id)) assert b'You never' in rv.data rv = self.app.get(url_for('place_delete', id_=place.id), follow_redirects=True) assert b'not possible if subunits' in rv.data rv = self.app.get(url_for('place_delete', id_=find_id), follow_redirects=True) assert b'The entry has been deleted.' in rv.data rv = self.app.get(url_for('place_delete', id_=place2.id), follow_redirects=True) assert b'The entry has been deleted.' in rv.data
def test_place(self): with app.app_context(): self.login() rv = self.app.get(url_for('place_insert')) assert b'+ Place' in rv.data with app.test_request_context(): app.preprocess_request() unit_node = NodeMapper.get_hierarchy_by_name('Administrative Unit') unit_sub1 = g.nodes[unit_node.subs[0]] unit_sub2 = g.nodes[unit_node.subs[1]] reference_id = EntityMapper.insert('E31', 'Ancient Books', 'edition').id place_node = NodeMapper.get_hierarchy_by_name('Place') source_id = EntityMapper.insert('E33', 'Tha source').id data = {'name': 'Asgard', 'alias-0': 'Valhöll', unit_node.id: '[' + str(unit_sub1.id) + ',' + str(unit_sub2.id) + ']'} rv = self.app.post(url_for('place_insert', origin_id=reference_id), data=data, follow_redirects=True) assert b'Asgard' in rv.data gis_points = """[{"type":"Feature", "geometry":{"type":"Point", "coordinates":[9,17]}, "properties":{"name":"Valhalla","description":"","shapeType":"centerpoint"}}]""" data['gis_points'] = gis_points data['gis_polygons'] = """[{"geometry":{ "coordinates":[[[9.75307425847859,17.8111792731339], [9.75315472474904,17.8110005175436],[9.75333711496205,17.8110873417098], [9.75307425847859,17.8111792731339]]],"type":"Polygon"}, "properties":{"count":4,"description":"","id":8,"name":"", "objectDescription":"","objectId":185,"shapeType":"Shape", "siteType":"Settlement","title":""},"type":"Feature"}]""" data[place_node.id] = place_node.subs data['continue_'] = 'yes' rv = self.app.post( url_for('place_insert', origin_id=source_id), data=data, follow_redirects=True) assert b'Tha source' in rv.data with app.test_request_context(): app.preprocess_request() places = EntityMapper.get_by_codes('place') place_id = places[0].id place2 = places[1] location = place2.get_linked_entity('P53') actor = EntityMapper.insert('E21', 'Milla Jovovich') actor.link('P74', location) assert b'Tha source' in rv.data rv = self.app.get(url_for('place_index')) assert b'Asgard' in rv.data rv = self.app.get(url_for('place_update', id_=place_id)) assert b'Valhalla' in rv.data data['continue_'] = '' data['alias-1'] = 'Val-hall' rv = self.app.post( url_for('place_update', id_=place_id), data=data, follow_redirects=True) assert b'Val-hall' in rv.data with app.test_request_context(): app.preprocess_request() event = EntityMapper.insert('E8', 'Valhalla rising') event.link('P7', location) event.link('P24', location) rv = self.app.get(url_for('place_view', id_=place2.id)) assert rv.data and b'Valhalla rising' in rv.data # Test invalid geom data['gis_polygons'] = """[{"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [ [[298.9893436362036, -5.888919049309554], [299.00444983737543, -5.9138487869408545], [299.00650977389887, -5.893358673645309], [298.9848804404028, -5.9070188333813585], [298.9893436362036, -5.888919049309554]]]}, "properties": {"name": "", "description": "", "shapeType": "shape"}}]""" rv = self.app.post( url_for('place_insert', origin_id=source_id), data=data, follow_redirects=True) assert b'An invalid geometry was entered' in rv.data # Place types rv = self.app.get(url_for('node_move_entities', id_=unit_sub1.id)) assert b'Asgard' in rv.data # Test move entities of multiple node if link to new node exists rv = self.app.post(url_for('node_move_entities', id_=unit_sub1.id), data={unit_node.id: unit_sub2.id, 'selection': location.id}, follow_redirects=True) assert b'Entities where updated' in rv.data # Test move entities of multiple node if link to new node doesn't exists rv = self.app.post(url_for('node_move_entities', id_=unit_sub2.id), data={unit_node.id: unit_sub1.id, 'selection': location.id}, follow_redirects=True) assert b'Entities where updated' in rv.data # Subunits with app.app_context(): self.app.get(url_for('place_insert', origin_id=place_id)) rv = self.app.post(url_for('place_insert', origin_id=place_id), data={'name': "It's not a bug, it's a feature!"}) feat_id = rv.location.split('/')[-1] self.app.get(url_for('place_insert', origin_id=feat_id)) self.app.get(url_for('place_update', id_=feat_id)) self.app.post(url_for('place_update', id_=feat_id), data={'name': "It's not a bug, it's a feature!"}) rv = self.app.post(url_for('place_insert', origin_id=feat_id), data={'name': "I'm a stratigraphic unit"}) stratigraphic_id = rv.location.split('/')[-1] self.app.get(url_for('place_insert', origin_id=stratigraphic_id)) self.app.get(url_for('place_update', id_=stratigraphic_id)) self.app.post(url_for('place_update', id_=stratigraphic_id), data={'name': "I'm a stratigraphic unit"}) dimension_node_id = NodeMapper.get_hierarchy_by_name('Dimensions').subs[0] data = {'name': 'You never find me', str(dimension_node_id): '50'} rv = self.app.post(url_for('place_insert', origin_id=stratigraphic_id), data=data) find_id = rv.location.split('/')[-1] self.app.get(url_for('place_update', id_=find_id)) self.app.post(url_for('place_update', id_=find_id), data=data) rv = self.app.get(url_for('place_view', id_=feat_id)) assert b'not a bug' in rv.data rv = self.app.get(url_for('place_view', id_=stratigraphic_id)) assert b'a stratigraphic unit' in rv.data rv = self.app.get(url_for('place_view', id_=find_id)) assert b'You never' in rv.data rv = self.app.get(url_for('place_delete', id_=place_id), follow_redirects=True) assert b'not possible if subunits' in rv.data rv = self.app.get(url_for('place_delete', id_=find_id), follow_redirects=True) assert b'The entry has been deleted.' in rv.data rv = self.app.get(url_for('place_delete', id_=place2.id), follow_redirects=True) assert b'The entry has been deleted.' in rv.data
def test_actor(self): with app.app_context(): self.login() rv = self.app.get(url_for('actor_index')) assert b'No entries' in rv.data # Create entities for actor rv = self.app.post(url_for('place_insert'), data={'name': 'Nostromos'}) residence_id = rv.location.split('/')[-1] with app.test_request_context(): app.preprocess_request() sex_node = NodeMapper.get_hierarchy_by_name('Sex') sex_node_sub_1 = g.nodes[sex_node.subs[0]] sex_node_sub_2 = g.nodes[sex_node.subs[1]] event_id = EntityMapper.insert('E8', 'Event Horizon').id source_id = EntityMapper.insert('E33', 'Tha source').id # Actor insert rv = self.app.get(url_for('actor_insert', code='E21')) assert b'+ Person' in rv.data self.app.get(url_for('actor_insert', code='E21', origin_id=residence_id)) data = { sex_node.id: sex_node_sub_1.id, 'name': 'Sigourney Weaver', 'alias-1': 'Ripley', 'residence': residence_id, 'appears_first': residence_id, 'appears_last': residence_id, 'description': 'Susan Alexandra Weaver is an American actress.', 'date_begin_year': '-1949', 'date_begin_month': '10', 'date_begin_day': '8', 'date_begin_year2': '-1948', 'date_end_year': '2049', 'date_end_year2': '2050', 'date_birth': True, 'date_death': True} rv = self.app.post( url_for('actor_insert', code='E21', origin_id=residence_id), data=data) actor_id = rv.location.split('/')[-1] # Test actor nodes rv = self.app.get(url_for('node_view', id_=sex_node_sub_1.id)) assert b'Susan' in rv.data rv = self.app.get(url_for('node_move_entities', id_=sex_node_sub_1.id)) assert b'Sigourney' in rv.data rv = self.app.post(url_for('node_move_entities', id_=sex_node_sub_1.id), data={sex_node.id: sex_node_sub_2.id, 'selection': [actor_id]}, follow_redirects=True) assert b'Entities where updated' in rv.data rv = self.app.post(url_for('node_move_entities', id_=sex_node_sub_2.id), data={sex_node.id: '', 'selection': [actor_id]}, follow_redirects=True) assert b'Entities where updated' in rv.data self.app.post(url_for('actor_insert', code='E21', origin_id=actor_id), data=data) self.app.post(url_for('actor_insert', code='E21', origin_id=event_id), data=data) self.app.post(url_for('actor_insert', code='E21', origin_id=source_id), data=data) rv = self.app.post(url_for('reference_insert', code='reference'), data={'name': 'Book'}) reference_id = rv.location.split('/')[-1] rv = self.app.post( url_for('actor_insert', code='E21', origin_id=reference_id), data=data, follow_redirects=True) assert b'An entry has been created' in rv.data data['continue_'] = 'yes' rv = self.app.post( url_for('actor_insert', code='E21'), data=data, follow_redirects=True) assert b'An entry has been created' in rv.data rv = self.app.get(url_for('actor_index')) assert b'Sigourney Weaver' in rv.data # Actor update rv = self.app.get(url_for('actor_update', id_=actor_id)) assert b'American actress' in rv.data data['name'] = 'Susan Alexandra Weaver' data['date_end_year'] = '' data['date_begin_year2'] = '1950' data['date_begin_day'] = '' rv = self.app.post( url_for('actor_update', id_=actor_id), data=data, follow_redirects=True) assert b'Susan Alexandra Weaver' in rv.data rv = self.app.post( url_for('ajax_bookmark'), data={'entity_id': actor_id}, follow_redirects=True) assert b'Remove bookmark' in rv.data rv = self.app.get('/') assert b'Weaver' in rv.data rv = self.app.post( url_for('ajax_bookmark'), data={'entity_id': actor_id}, follow_redirects=True) assert b'Bookmark' in rv.data rv = self.app.get(url_for('link_delete', origin_id=actor_id, id_=666), follow_redirects=True) assert b'removed'in rv.data # Actor delete rv = self.app.get(url_for('actor_delete', id_=actor_id), follow_redirects=True) assert b'The entry has been deleted.' in rv.data
def get_all( objects: Optional[List[Entity]] = None) -> Dict[str, List[Any]]: if objects is None: objects = [] all_: Dict[str, List[Any]] = { 'point': [], 'linestring': [], 'polygon': [] } selected: Dict[str, List[Any]] = { 'point': [], 'linestring': [], 'polygon': [], 'polygon_point': [] } # Workaround to include GIS features of a subunit which would be otherwise omitted subunit_selected_id = 0 if objects and objects[0].system_type in [ 'feature', 'find', 'stratigraphic unit' ]: subunit_selected_id = objects[0].id object_ids = [x.id for x in objects] polygon_point_sql = \ 'public.ST_AsGeoJSON(public.ST_PointOnSurface(polygon.geom)) AS polygon_point, ' for shape in ['point', 'polygon', 'linestring']: sql = """ SELECT object.id AS object_id, {shape}.id, {shape}.name, {shape}.description, {shape}.type, public.ST_AsGeoJSON({shape}.geom) AS geojson, {polygon_point_sql} object.name AS object_name, object.description AS object_desc, string_agg(CAST(t.range_id AS text), ',') AS types FROM model.entity place JOIN model.link l ON place.id = l.range_id JOIN model.entity object ON l.domain_id = object.id JOIN gis.{shape} {shape} ON place.id = {shape}.entity_id LEFT JOIN model.link t ON object.id = t.domain_id AND t.property_code = 'P2' WHERE place.class_code = 'E53' AND l.property_code = 'P53' AND (object.system_type = 'place' OR object.id = {subunit_selected_id}) GROUP BY object.id, {shape}.id;""".format( shape=shape, subunit_selected_id=subunit_selected_id, polygon_point_sql=polygon_point_sql if shape == 'polygon' else '') g.execute(sql) place_type_root_id = NodeMapper.get_hierarchy_by_name('Place').id for row in g.cursor.fetchall(): description = row.description.replace( '"', '\"') if row.description else '' object_desc = row.object_desc.replace( '"', '\"') if row.object_desc else '' item = { 'type': 'Feature', 'geometry': json.loads(row.geojson), 'properties': { 'objectId': row.object_id, 'objectName': row.object_name.replace('"', '\"'), 'objectDescription': object_desc, 'id': row.id, 'name': row.name.replace('"', '\"') if row.name else '', 'description': description, 'shapeType': row.type } } if hasattr(row, 'types') and row.types: nodes_list = ast.literal_eval('[' + row.types + ']') for node_id in list(set(nodes_list)): node = g.nodes[node_id] if node.root and node.root[-1] == place_type_root_id: item['properties'][ 'objectType'] = node.name.replace('"', '\"') break if row.object_id in object_ids: selected[shape].append(item) else: all_[shape].append(item) if hasattr(row, 'polygon_point'): polygon_point_item = dict( item) # make a copy to prevent overriding geometry polygon_point_item['geometry'] = json.loads( row.polygon_point) if row.object_id in object_ids: selected['polygon_point'].append(polygon_point_item) else: all_['point'].append(polygon_point_item) return { 'gisPointAll': json.dumps(all_['point']), 'gisPointSelected': json.dumps(selected['point']), 'gisLineAll': json.dumps(all_['linestring']), 'gisLineSelected': json.dumps(selected['linestring']), 'gisPolygonAll': json.dumps(all_['polygon']), 'gisPolygonSelected': json.dumps(selected['polygon']), 'gisPolygonPointSelected': json.dumps(selected['polygon_point']), 'gisAllSelected': json.dumps(selected['polygon'] + selected['linestring'] + selected['point']) }
def test_actor(self): with app.app_context(): self.login() rv = self.app.get(url_for('actor_index')) assert b'No entries' in rv.data # Create entities for actor rv = self.app.post(url_for('place_insert'), data={'name': 'Nostromos'}) residence_id = rv.location.split('/')[-1] with app.test_request_context(): app.preprocess_request() sex_node = NodeMapper.get_hierarchy_by_name('Sex') sex_node_sub_1 = g.nodes[sex_node.subs[0]] sex_node_sub_2 = g.nodes[sex_node.subs[1]] event = EntityMapper.insert('E8', 'Event Horizon') source = EntityMapper.insert('E33', 'Necronomicon') file = EntityMapper.insert('E31', 'X-Files', 'file') # Actor insert rv = self.app.get(url_for('actor_insert', code='E21')) assert b'+ Person' in rv.data self.app.get( url_for('actor_insert', code='E21', origin_id=residence_id)) data = { sex_node.id: sex_node_sub_1.id, 'name': 'Sigourney Weaver', 'alias-1': 'Ripley', 'residence': residence_id, 'begins_in': residence_id, 'ends_in': residence_id, 'description': 'Susan Alexandra Weaver is an American actress.', 'begin_year_from': '-1949', 'begin_month_from': '10', 'begin_day_from': '8', 'begin_year_to': '-1948', 'end_year_from': '2049', 'end_year_to': '2050' } rv = self.app.post(url_for('actor_insert', code='E21', origin_id=residence_id), data=data) actor_id = rv.location.split('/')[-1] # Test actor nodes rv = self.app.get(url_for('node_view', id_=sex_node_sub_1.id)) assert b'Susan' in rv.data rv = self.app.get( url_for('node_move_entities', id_=sex_node_sub_1.id)) assert b'Sigourney' in rv.data rv = self.app.post(url_for('node_move_entities', id_=sex_node_sub_1.id), data={ sex_node.id: sex_node_sub_2.id, 'selection': [actor_id], 'checkbox_values': str([actor_id]) }, follow_redirects=True) assert b'Entities where updated' in rv.data rv = self.app.post(url_for('node_move_entities', id_=sex_node_sub_2.id), data={ sex_node.id: '', 'selection': [actor_id], 'checkbox_values': str([actor_id]) }, follow_redirects=True) assert b'Entities where updated' in rv.data self.app.post(url_for('actor_insert', code='E21', origin_id=actor_id), data=data) self.app.post(url_for('actor_insert', code='E21', origin_id=event.id), data=data) self.app.post(url_for('actor_insert', code='E21', origin_id=source.id), data=data) rv = self.app.post(url_for('reference_insert', code='external_reference'), data={'name': 'https://openatlas.eu'}) reference_id = rv.location.split('/')[-1] rv = self.app.post(url_for('actor_insert', code='E21', origin_id=reference_id), data=data, follow_redirects=True) assert b'An entry has been created' in rv.data data['continue_'] = 'yes' rv = self.app.post(url_for('actor_insert', code='E21'), data=data, follow_redirects=True) assert b'An entry has been created' in rv.data rv = self.app.get(url_for('actor_index')) assert b'Sigourney Weaver' in rv.data # Add to actor rv = self.app.get(url_for('actor_add_file', id_=actor_id)) assert b'Add File' in rv.data rv = self.app.post(url_for('actor_add_file', id_=actor_id), data={'checkbox_values': str([file.id])}, follow_redirects=True) assert b'X-Files' in rv.data rv = self.app.get(url_for('actor_add_source', id_=actor_id)) assert b'Add Source' in rv.data rv = self.app.post(url_for('actor_add_source', id_=actor_id), data={'checkbox_values': str([source.id])}, follow_redirects=True) assert b'Necronomicon' in rv.data rv = self.app.get(url_for('actor_add_reference', id_=actor_id)) assert b'Add Reference' in rv.data rv = self.app.post(url_for('actor_add_reference', id_=actor_id), data={ 'reference': reference_id, 'page': '777' }, follow_redirects=True) assert b'777' in rv.data # Actor update rv = self.app.get(url_for('actor_update', id_=actor_id)) assert b'American actress' in rv.data data['name'] = 'Susan Alexandra Weaver' data['alias-1'] = 'Ripley1' data['end_year_from'] = '' data['begin_year_to'] = '1950' data['begin_day_from'] = '' rv = self.app.post(url_for('actor_update', id_=actor_id), data=data, follow_redirects=True) assert b'Susan Alexandra Weaver' in rv.data rv = self.app.post(url_for('ajax_bookmark'), data={'entity_id': actor_id}, follow_redirects=True) assert b'Remove bookmark' in rv.data rv = self.app.get('/') assert b'Weaver' in rv.data rv = self.app.post(url_for('ajax_bookmark'), data={'entity_id': actor_id}, follow_redirects=True) assert b'Bookmark' in rv.data rv = self.app.get(url_for('link_delete', origin_id=actor_id, id_=666), follow_redirects=True) assert b'removed' in rv.data # Actor delete rv = self.app.get(url_for('actor_delete', id_=actor_id), follow_redirects=True) assert b'The entry has been deleted.' in rv.data
def test_relation(self): with app.app_context(): self.login() with app.test_request_context(): app.preprocess_request() actor_id = EntityMapper.insert('E21', 'Connor MacLeod').id related_id = EntityMapper.insert('E21', 'The Kurgan').id # Add relationship rv = self.app.get(url_for('relation_insert', origin_id=actor_id)) assert b'Actor Actor Relation' in rv.data relation_id = NodeMapper.get_hierarchy_by_name( 'Actor Actor Relation').id data = { 'actor': '[' + str(related_id) + ']', relation_id: relation_id, 'inverse': None, 'date_begin_year': '-1949', 'date_begin_month': '10', 'date_begin_day': '8', 'date_begin_year2': '-1948', 'date_end_year': '2049', 'date_end_year2': '2050' } rv = self.app.post(url_for('relation_insert', origin_id=actor_id), data=data, follow_redirects=True) assert b'The Kurgan' in rv.data data['continue_'] = 'yes' data['inverse'] = True rv = self.app.post(url_for('relation_insert', origin_id=actor_id), data=data, follow_redirects=True) assert b'The Kurgan' in rv.data rv = self.app.get(url_for('actor_view', id_=actor_id)) assert b'The Kurgan' in rv.data rv = self.app.post(url_for('relation_insert', origin_id=related_id), data=data, follow_redirects=True) assert b"Can't link to itself." in rv.data # Update relationship with app.test_request_context(): app.preprocess_request() link_id = LinkMapper.get_links(actor_id, 'OA7')[0].id link_id2 = LinkMapper.get_links(actor_id, 'OA7', True)[0].id rv = self.app.get( url_for('relation_update', id_=link_id, origin_id=related_id)) assert b'Connor' in rv.data rv = self.app.post(url_for('relation_update', id_=link_id, origin_id=actor_id), data={ 'description': 'There can be only one!', 'inverse': True }, follow_redirects=True) assert b'only one' in rv.data rv = self.app.post(url_for('relation_update', id_=link_id2, origin_id=actor_id), data={ 'description': 'There can be only one!', 'inverse': None }, follow_redirects=True) assert b'only one' in rv.data
def test_involvement(self): with app.app_context(): self.login() rv = self.app.post(url_for('event_insert', code='E8'), data={ 'name': 'Event Horizon', 'begin_year_from': '949', 'begin_month_from': '10', 'begin_day_from': '8', 'end_year_from': '1951' }) event_id = int(rv.location.split('/')[-1]) with app.test_request_context(): app.preprocess_request() actor = EntityMapper.insert('E21', 'Captain Miller') involvement = NodeMapper.get_hierarchy_by_name('Involvement') # Add involvement rv = self.app.get(url_for('involvement_insert', origin_id=actor.id)) assert b'Involvement' in rv.data data = { 'event': str([event_id]), 'activity': 'P11', 'begin_year_from': '950', 'end_year_from': '1950', involvement.id: involvement.id } rv = self.app.post(url_for('involvement_insert', origin_id=actor.id), data=data, follow_redirects=True) assert b'Event Horizon' in rv.data data = { 'actor': str([actor.id]), 'continue_': 'yes', 'activity': 'P22' } rv = self.app.post(url_for('involvement_insert', origin_id=event_id), data=data, follow_redirects=True) assert b'Event Horizon' in rv.data rv = self.app.get(url_for('event_view', id_=event_id)) assert b'Event Horizon' in rv.data rv = self.app.get(url_for('actor_view', id_=actor.id)) assert b'Appears first' in rv.data # Update involvement with app.test_request_context(): app.preprocess_request() link_id = LinkMapper.get_links(event_id, 'P22')[0].id rv = self.app.get( url_for('involvement_update', id_=link_id, origin_id=event_id)) assert b'Captain' in rv.data rv = self.app.post(url_for('involvement_update', id_=link_id, origin_id=actor.id), data={ 'description': 'Infinite Space - Infinite Terror', 'activity': 'P23' }, follow_redirects=True) assert b'Infinite Space - Infinite Terror' in rv.data rv = self.app.get(url_for('actor_view', id_=actor.id)) assert b'Appears first' in rv.data rv = self.app.get(url_for('event_view', id_=event_id)) assert b'Infinite Space - Infinite Terror' in rv.data
def test_admin(self) -> None: with app.app_context(): self.login() rv = self.app.get(url_for('admin_mail')) assert b'Email from' in rv.data rv = self.app.get(url_for('admin_index')) assert b'User' in rv.data rv = self.app.get(url_for('admin_general')) assert b'Edit' in rv.data rv = self.app.get(url_for('admin_general_update')) assert b'Save' in rv.data rv = self.app.get(url_for('admin_map')) assert b'MaxClusterRadius' in rv.data rv = self.app.post(url_for('admin_map'), follow_redirects=True, data={ 'map_cluster_enabled': True, 'map_cluster_max_radius': 2, 'map_cluster_disable_at_zoom': 5 }) assert b'Changes have been saved.' in rv.data # Check link duplicates and multi use of single nodes with app.test_request_context(): app.preprocess_request() event = EntityMapper.insert('E8', 'Event Horizon') source = EntityMapper.insert('E33', 'Tha source') source.link('P67', event) source.link('P67', event) source_node = NodeMapper.get_hierarchy_by_name('Source') source.link('P2', source_node.subs[0]) source.link('P2', source_node.subs[1]) rv = self.app.get(url_for('admin_check_link_duplicates')) assert b'Event Horizon' in rv.data rv = self.app.get(url_for('admin_check_link_duplicates', delete='delete'), follow_redirects=True) assert b'Remove' in rv.data rv = self.app.get(url_for('admin_delete_single_type_duplicate', entity_id=source.id, node_id=source_node.subs[0]), follow_redirects=True) assert b'Congratulations, everything looks fine!' in rv.data # Check similar names with app.test_request_context(): app.preprocess_request() EntityMapper.insert('E21', 'I have the same name!') EntityMapper.insert('E21', 'I have the same name!') rv = self.app.post(url_for('admin_check_similar'), follow_redirects=True, data={ 'classes': 'actor', 'ratio': 100 }) assert b'I have the same name!' in rv.data rv = self.app.post(url_for('admin_check_similar'), follow_redirects=True, data={ 'classes': 'file', 'ratio': 100 }) assert b'No entries' in rv.data data = {name: '' for name in SettingsMapper.fields } # type: Dict[str, Union[str, int]] data['default_language'] = 'en' data['default_table_rows'] = '10' data['failed_login_forget_minutes'] = '10' data['failed_login_tries'] = '10' data['minimum_password_length'] = '10' data['random_password_length'] = '10' data['reset_confirm_hours'] = '10' data['log_level'] = '0' data['site_name'] = 'Nostromo' data['minimum_jstree_search'] = 3 data['minimum_tablesorter_search'] = 4 rv = self.app.post(url_for('admin_general_update'), data=data, follow_redirects=True) assert b'Nostromo' in rv.data rv = self.app.get(url_for('admin_mail_update')) assert b'Mail transport port' in rv.data data = { 'mail': True, 'mail_transport_username': '******', 'mail_transport_host': 'localhost', 'mail_transport_port': '23', 'mail_from_email': '*****@*****.**', 'mail_from_name': 'Max Headroom', 'mail_recipients_feedback': '*****@*****.**' } rv = self.app.post(url_for('admin_mail_update'), data=data, follow_redirects=True) assert b'Max Headroom' in rv.data rv = self.app.get(url_for('admin_file')) assert b'jpg' in rv.data rv = self.app.post(url_for('admin_file'), data={ 'file_upload_max_size': 20, 'profile_image_width': 20 }, follow_redirects=True) assert b'Changes have been saved.' in rv.data
def test_relation(self): with app.app_context(): self.login() with app.test_request_context(): app.preprocess_request() actor = EntityMapper.insert('E21', 'Connor MacLeod') related = EntityMapper.insert('E21', 'The Kurgan') # Add relationship rv = self.app.get(url_for('relation_insert', origin_id=actor.id)) assert b'Actor Actor Relation' in rv.data relation_id = NodeMapper.get_hierarchy_by_name( 'Actor Actor Relation').id relation_sub_id = g.nodes[relation_id].subs[0] relation_sub_id2 = g.nodes[relation_id].subs[1] data = { 'actor': str([related.id]), relation_id: relation_sub_id, 'inverse': None, 'begin_year_from': '-1949', 'begin_month_from': '10', 'begin_day_from': '8', 'begin_year_to': '-1948', 'end_year_from': '2049', 'end_year_to': '2050' } rv = self.app.post(url_for('relation_insert', origin_id=actor.id), data=data, follow_redirects=True) assert b'The Kurgan' in rv.data rv = self.app.get(url_for('node_view', id_=relation_sub_id)) assert b'Connor' in rv.data data['continue_'] = 'yes' data['inverse'] = True rv = self.app.post(url_for('relation_insert', origin_id=actor.id), data=data, follow_redirects=True) assert b'The Kurgan' in rv.data rv = self.app.get(url_for('actor_view', id_=actor.id)) assert b'The Kurgan' in rv.data rv = self.app.post(url_for('relation_insert', origin_id=related.id), data=data, follow_redirects=True) assert b"Can't link to itself." in rv.data # Relation types rv = self.app.get( url_for('node_move_entities', id_=relation_sub_id)) assert b'The Kurgan' in rv.data # Update relationship with app.test_request_context(): app.preprocess_request() link_id = LinkMapper.get_links(actor.id, 'OA7')[0].id link_id2 = LinkMapper.get_links(actor.id, 'OA7', True)[0].id rv = self.app.post(url_for('node_move_entities', id_=relation_sub_id), data={ relation_id: relation_sub_id2, 'selection': [link_id], 'checkbox_values': str([link_id]) }, follow_redirects=True) assert b'Entities where updated' in rv.data rv = self.app.post(url_for('node_move_entities', id_=relation_sub_id2), data={ relation_id: '', 'selection': [link_id], 'checkbox_values': str([link_id]) }, follow_redirects=True) assert b'Entities where updated' in rv.data rv = self.app.get( url_for('relation_update', id_=link_id, origin_id=related.id)) assert b'Connor' in rv.data rv = self.app.post(url_for('relation_update', id_=link_id, origin_id=actor.id), data={ 'description': 'There can be only one!', 'inverse': True }, follow_redirects=True) assert b'only one' in rv.data rv = self.app.post(url_for('relation_update', id_=link_id2, origin_id=actor.id), data={ 'description': 'There can be only one!', 'inverse': None }, follow_redirects=True) assert b'only one' in rv.data