def search(term, codes, description=False, own=False): sql = EntityMapper.sql if own: sql += " LEFT JOIN web.user_log ul ON e.id = ul.entity_id " sql += " WHERE LOWER(e.name) LIKE LOWER(%(term)s)" sql += " OR lower(e.description) LIKE lower(%(term)s) AND " if description else " AND " sql += " ul.user_id = %(user_id)s AND " if own else '' sql += " e.class_code IN %(codes)s" sql += " GROUP BY e.id ORDER BY e.name" g.cursor.execute( sql, { 'term': '%' + term + '%', 'codes': tuple(codes), 'user_id': current_user.id }) debug_model['div sql'] += 1 entities = [] for row in g.cursor.fetchall(): if row.class_code == 'E82': # If found in actor alias entities.append( LinkMapper.get_linked_entity(row.id, 'P131', True)) elif row.class_code == 'E41': # If found in place alias entities.append( LinkMapper.get_linked_entity(row.id, 'P1', True)) else: entities.append(Entity(row)) return entities
def relation_update(id_: int, origin_id: int) -> str: link_ = LinkMapper.get_by_id(id_) domain = EntityMapper.get_by_id(link_.domain.id) range_ = EntityMapper.get_by_id(link_.range.id) origin = range_ if origin_id == range_.id else domain related = range_ if origin_id == domain.id else domain form = build_form(RelationForm, 'Actor Actor Relation', link_, request) del form.actor, form.insert_and_continue, form.origin_id if form.validate_on_submit(): g.cursor.execute('BEGIN') try: link_.delete() if form.inverse.data: link_ = LinkMapper.get_by_id(related.link('OA7', origin, form.description.data)) else: link_ = LinkMapper.get_by_id(origin.link('OA7', related, form.description.data)) link_.set_dates(form) link_.type = get_link_type(form) link_.update() g.cursor.execute('COMMIT') flash(_('info update'), 'info') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') return redirect(url_for('actor_view', id_=origin.id) + '#tab-relation') if origin.id == range_.id: form.inverse.data = True form.save.label.text = _('save') form.populate_dates(link_) return render_template('relation/update.html', origin=origin, form=form, related=related)
def relation_insert(origin_id: int) -> str: origin = EntityMapper.get_by_id(origin_id) form = build_form(RelationForm, 'Actor Actor Relation') form.origin_id.data = origin.id if form.validate_on_submit(): g.cursor.execute('BEGIN') try: for actor in EntityMapper.get_by_ids(ast.literal_eval(form.actor.data)): if form.inverse.data: link_ = LinkMapper.get_by_id(actor.link('OA7', origin, form.description.data)) else: link_ = LinkMapper.get_by_id(origin.link('OA7', actor, form.description.data)) link_.set_dates(form) link_.type = get_link_type(form) link_.update() g.cursor.execute('COMMIT') flash(_('entity created'), 'info') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') if form.continue_.data == 'yes': return redirect(url_for('relation_insert', origin_id=origin_id)) return redirect(url_for('actor_view', id_=origin.id) + '#tab-relation') return render_template('relation/insert.html', origin=origin, form=form)
def admin_check_link_duplicates(delete: Optional[str] = None) -> str: if delete: delete_count = str(LinkMapper.delete_link_duplicates()) logger.log('info', 'admin', 'Deleted duplicate links: ' + delete_count) flash(_('deleted links') + ': ' + delete_count, 'info') return redirect(url_for('admin_check_link_duplicates')) table = Table(['domain', 'range', 'property_code', 'description', 'type_id', 'begin_from', 'begin_to', 'begin_comment', 'end_from', 'end_to', 'end_comment', 'count']) for result in LinkMapper.check_link_duplicates(): table.rows.append([link(EntityMapper.get_by_id(result.domain_id)), link(EntityMapper.get_by_id(result.range_id)), link(g.properties[result.property_code]), truncate_string(result.description), link(g.nodes[result.type_id]) if result.type_id else '', format_date(result.begin_from), format_date(result.begin_to), truncate_string(result.begin_comment), format_date(result.end_from), format_date(result.end_to), truncate_string(result.end_comment), result.count]) duplicates = False if table.rows: duplicates = True else: # If no exact duplicates where found check if single types are used multiple times table = Table(['entity', 'class', 'base type', 'incorrect multiple types'], rows=LinkMapper.check_single_type_duplicates()) return render_template('admin/check_link_duplicates.html', table=table, duplicates=duplicates)
def member_update(id_: int, origin_id: int) -> str: link_ = LinkMapper.get_by_id(id_) domain = EntityMapper.get_by_id(link_.domain.id) range_ = EntityMapper.get_by_id(link_.range.id) origin = range_ if origin_id == range_.id else domain form = build_form(MemberForm, 'Member', link_, request) del form.actor, form.group, form.insert_and_continue if form.validate_on_submit(): g.cursor.execute('BEGIN') try: link_.delete() link_ = LinkMapper.get_by_id( domain.link('P107', range_, form.description.data)) link_.set_dates(form) link_.type = get_link_type(form) link_.update() g.cursor.execute('COMMIT') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') tab = '#tab-member-of' if origin.id == range_.id else '#tab-member' return redirect(url_for('actor_view', id_=origin.id) + tab) form.save.label.text = _('save') form.populate_dates(link_) related = range_ if origin_id == domain.id else domain return render_template('member/update.html', origin=origin, form=form, related=related)
def save(form, event=None, code=None, origin=None): g.cursor.execute('BEGIN') try: if event: log_action = 'update' LinkMapper.delete_by_codes(event, ['P117', 'P7', 'P24']) else: log_action = 'insert' event = EntityMapper.insert(code, form.name.data) event.name = form.name.data event.description = form.description.data event.update() event.save_dates(form) event.save_nodes(form) if form.event.data: event.link('P117', int(form.event.data)) if form.place.data: place = LinkMapper.get_linked_entity(int(form.place.data), 'P53') event.link('P7', place) if event.class_.code == 'E8' and form.given_place.data: # Link place for acquisition event.link('P24', ast.literal_eval(form.given_place.data)) url = url_for('event_view', id_=event.id) if origin: view_name = get_view_name(origin) url = url_for(view_name + '_view', id_=origin.id) + '#tab-event' if view_name == 'reference': link_id = origin.link('P67', event) url = url_for('reference_link_update', link_id=link_id, origin_id=origin.id) elif view_name == 'source': origin.link('P67', event) elif view_name == 'actor': link_id = event.link('P11', origin) url = url_for('involvement_update', id_=link_id, origin_id=origin.id) elif view_name == 'file': origin.link('P67', event) if form.continue_.data == 'yes': url = url_for('event_insert', code=code, origin_id=origin.id if origin else None) g.cursor.execute('COMMIT') logger.log_user(event.id, log_action) flash( _('entity created') if log_action == 'insert' else _('info update'), 'info') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') url = url_for('event_index') return url
def get_invalid_link_dates(): """ Search for links with invalid date combinations, e.g. begin after end""" sql = """ SELECT l.id FROM model.link l LEFT JOIN model.link_property bl1 ON l.id = bl1.domain_id AND bl1.property_code IN ('OA1', 'OA3', 'OA5') LEFT JOIN model.entity b1 ON bl1.range_id = b1.id AND b1.system_type IN ('from date value', 'exact date value') LEFT JOIN model.link_property bl2 ON l.id = bl2.domain_id AND bl2.property_code IN ('OA1', 'OA3', 'OA5') LEFT JOIN model.entity b2 ON bl2.range_id = b2.id AND b2.system_type = 'to date value' LEFT JOIN model.link_property el1 ON l.id = el1.domain_id AND el1.property_code IN ('OA2', 'OA4', 'OA6') LEFT JOIN model.entity e1 ON el1.range_id = e1.id AND e1.system_type IN ('from date value', 'exact date value') LEFT JOIN model.link_property el2 ON l.id = el2.domain_id AND el2.property_code IN ('OA2', 'OA4', 'OA6') LEFT JOIN model.entity e2 ON el2.range_id = e2.id AND e2.system_type = 'to date value' GROUP BY l.id HAVING l.property_code IN ('OA7', 'P107', 'P11', 'P14', 'P22', 'P23') AND (max(b1.value_timestamp) > max(b2.value_timestamp) OR max(e1.value_timestamp) > max(e2.value_timestamp) OR (max(b1.value_timestamp) IS NOT NULL AND max(e1.value_timestamp) IS NOT NULL AND max(b1.value_timestamp) > max(e1.value_timestamp)) OR (max(b2.value_timestamp) IS NOT NULL AND max(e2.value_timestamp) IS NOT NULL AND max(b2.value_timestamp) > max(e2.value_timestamp)));""" g.cursor.execute(sql) debug_model['div sql'] += 1 return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
def admin_check_links(check: Optional[str] = None) -> str: table = None if check: table = Table(['domain', 'property', 'range']) for result in LinkMapper.check_links(): # pragma: no cover table.rows.append([result['domain'], result['property'], result['range']]) return render_template('admin/check_links.html', table=table, check=check)
def member_update(id_, origin_id): link_ = LinkMapper.get_by_id(id_) domain = EntityMapper.get_by_id(link_.domain.id) range_ = EntityMapper.get_by_id(link_.range.id) origin = range_ if origin_id == range_.id else domain form = build_form(MemberForm, 'Member', link_, request) del form.actor, form.group, form.insert_and_continue if form.validate_on_submit(): g.cursor.execute('BEGIN') try: link_.delete() link_id = domain.link('P107', range_, form.description.data) DateMapper.save_link_dates(link_id, form) NodeMapper.save_link_nodes(link_id, form) g.cursor.execute('COMMIT') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') tab = '#tab-member-of' if origin.id == range_.id else '#tab-member' return redirect(url_for('actor_view', id_=origin.id) + tab) form.save.label.text = _('save') link_.set_dates() form.populate_dates(link_) related = range_ if origin_id == domain.id else domain return render_template('member/update.html', origin=origin, form=form, related=related)
def relation_update(id_, origin_id): link_ = LinkMapper.get_by_id(id_) domain = EntityMapper.get_by_id(link_.domain.id) range_ = EntityMapper.get_by_id(link_.range.id) origin = range_ if origin_id == range_.id else domain related = range_ if origin_id == domain.id else domain form = build_form(RelationForm, 'Actor Actor Relation', link_, request) del form.actor, form.insert_and_continue, form.origin_id if form.validate_on_submit(): g.cursor.execute('BEGIN') try: link_.delete() if form.inverse.data: link_id = related.link('OA7', origin, form.description.data) else: link_id = origin.link('OA7', related, form.description.data) DateMapper.save_link_dates(link_id, form) NodeMapper.save_link_nodes(link_id, form) g.cursor.execute('COMMIT') flash(_('info update'), 'info') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') return redirect(url_for('actor_view', id_=origin.id) + '#tab-relation') if origin.id == range_.id: form.inverse.data = True form.save.label.text = _('save') link_.set_dates() form.populate_dates(link_) return render_template('relation/update.html', origin=origin, form=form, related=related)
def source_add(origin_id): """ Link an entity to source coming from the entity.""" origin = EntityMapper.get_by_id(origin_id) if request.method == 'POST': g.cursor.execute('BEGIN') try: for value in request.form.getlist('values'): LinkMapper.insert(int(value), 'P67', origin.id) g.cursor.execute('COMMIT') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') return redirect(url_for(get_view_name(origin) + '_view', id_=origin.id) + '#tab-source') form = build_table_form('source', origin.get_linked_entities('P67', True)) return render_template('source/add.html', origin=origin, form=form)
def involvement_update(id_, origin_id): link_ = LinkMapper.get_by_id(id_) event = EntityMapper.get_by_id(link_.domain.id) actor = EntityMapper.get_by_id(link_.range.id) origin = event if origin_id == event.id else actor form = build_form(ActorForm, 'Involvement', link_, request) form.save.label.text = _('save') del form.actor, form.event, form.insert_and_continue form.activity.choices = [('P11', g.properties['P11'].name)] if event.class_.code in ['E7', 'E8', 'E12']: form.activity.choices.append(('P14', g.properties['P14'].name)) if event.class_.code == 'E8': form.activity.choices.append(('P22', g.properties['P22'].name)) form.activity.choices.append(('P23', g.properties['P23'].name)) if form.validate_on_submit(): g.cursor.execute('BEGIN') try: link_.delete() link_id = event.link(form.activity.data, actor, form.description.data) DateMapper.save_link_dates(link_id, form) NodeMapper.save_link_nodes(link_id, form) g.cursor.execute('COMMIT') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') tab = 'actor' if origin.view_name == 'event' else 'event' return redirect(url_for(origin.view_name + '_view', id_=origin.id) + '#tab-' + tab) form.activity.data = link_.property.code form.description.data = link_.description link_.set_dates() form.populate_dates(link_) return render_template('involvement/update.html', origin=origin, form=form, linked_object=event if origin_id != event.id else actor)
def build_move_form(form, node) -> Form: root = g.nodes[node.root[-1]] setattr(form, str(root.id), TreeField(str(root.id))) form_instance = form(obj=node) # Delete custom fields except the ones specified for the form delete_list = [] # Can't delete fields in the loop so creating a list for later deletion for field in form_instance: if type(field) is TreeField and int(field.id) != root.id: delete_list.append(field.id) for item in delete_list: delattr(form_instance, item) choices = [] if root.class_.code == 'E53': for entity in node.get_linked_entities('P89', True): place = entity.get_linked_entity('P53', True) if place: choices.append((entity.id, place.name)) elif root.name in app.config['PROPERTY_TYPES']: for row in LinkMapper.get_entities_by_node(node): domain = EntityMapper.get_by_id(row.domain_id) range_ = EntityMapper.get_by_id(row.range_id) choices.append((row.id, domain.name + ' - ' + range_.name)) else: for entity in node.get_linked_entities('P2', True): choices.append((entity.id, entity.name)) form_instance.selection.choices = choices return form_instance
def build_move_form(form, node) -> Form: root = g.nodes[node.root[-1]] setattr(form, str(root.id), TreeField(str(root.id))) form_instance = form(obj=node) # Delete custom fields except the ones specified for the form delete_list = [ ] # Can't delete fields in the loop so creating a list for later deletion for field in form_instance: if type(field) is TreeField and int(field.id) != root.id: delete_list.append(field.id) for item in delete_list: delattr(form_instance, item) choices = [] if root.class_.code == 'E53': for entity in node.get_linked_entities('P89', True): place = entity.get_linked_entity('P53', True) if place: choices.append((entity.id, place.name)) elif root.name in app.config['PROPERTY_TYPES']: for row in LinkMapper.get_entities_by_node(node): domain = EntityMapper.get_by_id(row.domain_id) range_ = EntityMapper.get_by_id(row.range_id) choices.append((row.id, domain.name + ' - ' + range_.name)) else: for entity in node.get_linked_entities('P2', True): choices.append((entity.id, entity.name)) form_instance.selection.choices = choices return form_instance
def test_model(self): with app.app_context(): rv = self.app.get(url_for('model_index')) assert b'Browse' in rv.data rv = self.app.get(url_for('class_index')) assert b'E1' in rv.data rv = self.app.get(url_for('class_view', code='E4')) assert b'Domain for' in rv.data rv = self.app.get(url_for('property_index')) assert b'P1' in rv.data rv = self.app.get(url_for('property_view', code='P68')) assert b'P68' in rv.data data = {'domain': 'E1', 'range': 'E1', 'property': 'P13'} rv = self.app.post(url_for('model_index'), data=data) assert b'Wrong domain' in rv.data data = {'domain': 'E1', 'range': 'E1', 'property': 'P67'} rv = self.app.post(url_for('model_index'), data=data) assert b'Wrong domain' in rv.data self.login() with app.test_request_context( ): # Insert data to display in network view app.preprocess_request() actor = EntityMapper.insert('E21', 'King Arthur') event = EntityMapper.insert('E7', 'Battle of Camlann') prop_object = EntityMapper.insert('E89', 'Propositional Object') LinkMapper.insert(actor, 'P11', event) LinkMapper.insert(actor, 'P67', prop_object) rv = self.app.get(url_for('model_network')) assert b'Orphans' in rv.data data = { 'orphans': True, 'width': 100, 'height': 40, 'distance': -666, 'charge': 500 } rv = self.app.post(url_for('model_network'), data=data) assert b'666' in rv.data # Translations self.app.get('/index/setlocale/de') rv = self.app.get(url_for('property_view', code='P68')) assert b'verweist auf' in rv.data rv = self.app.get(url_for('class_view', code='E4')) assert b'Phase' in rv.data
def reference_view(id_, unlink_id=None): reference = EntityMapper.get_by_id(id_) if unlink_id: LinkMapper.delete_by_id(unlink_id) flash(_('link removed'), 'info') tables = { 'info': get_entity_data(reference), 'file': { 'id': 'files', 'data': [], 'header': app.config['TABLE_HEADERS']['file'] + ['page'] } } for name in [ 'source', 'event', 'actor', 'place', 'feature', 'stratigraphic-unit', 'find' ]: header = app.config['TABLE_HEADERS'][name] + ['page'] tables[name] = {'id': name, 'header': header, 'data': []} for link_ in reference.get_links('P67', True): data = get_base_table_data(link_.domain) if is_authorized('editor'): unlink = url_for('reference_view', id_=reference.id, unlink_id=link_.id) + '#tab-file' data.append(display_remove_link(unlink, link_.domain.name)) tables['file']['data'].append(data) for link_ in reference.get_links(['P67', 'P128']): view_name = get_view_name(link_.range) view_name = view_name if view_name != 'place' else link_.range.system_type.replace( ' ', '-') data = get_base_table_data(link_.range) data.append(truncate_string(link_.description)) if is_authorized('editor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=reference.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') unlink_url = url_for('reference_view', id_=reference.id, unlink_id=link_.id) + '#tab-' + view_name data.append(display_remove_link(unlink_url, link_.range.name)) tables[view_name]['data'].append(data) return render_template('reference/view.html', reference=reference, tables=tables)
def link(self, code: str, range_, description: Optional[str] = None, inverse: Optional[bool] = False, type_id: Optional[int] = None) -> Union[int, None]: return LinkMapper.insert(self, code, range_, description, inverse, type_id)
def get_linked_entities(self, code: str, inverse: Optional[bool] = False, nodes: Optional[bool] = False): return LinkMapper.get_linked_entities(self, code, inverse=inverse, nodes=nodes)
def get_linked_entities(self, code: Union[str, List[str]], inverse: bool = False, nodes: bool = False) -> List[Entity]: return LinkMapper.get_linked_entities(self.id, code, inverse=inverse, nodes=nodes)
def involvement_insert(origin_id: int) -> str: origin = EntityMapper.get_by_id(origin_id) form = build_form(ActorForm, 'Involvement') if origin.view_name == 'event': del form.event else: del form.actor form.activity.choices = [('P11', g.properties['P11'].name_inverse)] if origin.class_.code in ['E7', 'E8']: form.activity.choices.append(('P14', g.properties['P14'].name_inverse)) if origin.class_.code == 'E8': form.activity.choices.append(('P22', g.properties['P22'].name_inverse)) form.activity.choices.append(('P23', g.properties['P23'].name_inverse)) if form.validate_on_submit(): g.cursor.execute('BEGIN') try: if origin.view_name == 'event': for actor in EntityMapper.get_by_ids( ast.literal_eval(form.actor.data)): link_ = LinkMapper.get_by_id( origin.link(form.activity.data, actor, form.description.data)) link_.set_dates(form) link_.type = get_link_type(form) link_.update() else: for event in EntityMapper.get_by_ids( ast.literal_eval(form.event.data)): link_ = LinkMapper.get_by_id( event.link(form.activity.data, origin, form.description.data)) link_.set_dates(form) link_.type = get_link_type(form) link_.update() g.cursor.execute('COMMIT') flash(_('entity created'), 'info') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') if form.continue_.data == 'yes': return redirect(url_for('involvement_insert', origin_id=origin_id)) tab = 'actor' if origin.view_name == 'event' else 'event' return redirect( url_for(origin.view_name + '_view', id_=origin.id) + '#tab-' + tab) return render_template('involvement/insert.html', origin=origin, form=form)
def link(self, code: str, range_: Union[Entity, List[Entity]], description: Optional[str] = None, inverse: bool = False, type_id: Optional[int] = None) -> List[int]: return LinkMapper.insert(self, code, range_, description, inverse, type_id)
def get_linked_entity(self, code: str, inverse: bool = False, nodes: bool = False) -> Optional[Entity]: return LinkMapper.get_linked_entity(self.id, code, inverse=inverse, nodes=nodes)
def test_member(self): with app.app_context(): self.login() with app.test_request_context(): app.preprocess_request() actor = EntityMapper.insert('E21', 'Ripley') group = EntityMapper.insert('E74', 'Space Marines') # Add membership rv = self.app.get(url_for('member_insert', origin_id=group.id)) assert b'Actor Function' in rv.data data = {'group': str([group.id])} rv = self.app.post(url_for('membership_insert', origin_id=actor.id), data=data, follow_redirects=True) assert b'Space Marines' in rv.data data = {'group': str([group.id]), 'continue_': 'yes'} rv = self.app.post(url_for('membership_insert', origin_id=actor.id), data=data, follow_redirects=True) assert b'Space Marines' in rv.data rv = self.app.post(url_for('membership_insert', origin_id=group.id), data=data, follow_redirects=True) assert b"Can't link to itself" in rv.data rv = self.app.post(url_for('member_insert', origin_id=actor.id), data={'actor': str([actor.id])}, follow_redirects=True) assert b"Can't link to itself" in rv.data # Add member to group data = {'actor': str([actor.id])} rv = self.app.post(url_for('member_insert', origin_id=group.id), data=data, follow_redirects=True) assert b'Ripley' in rv.data data['continue_'] = 'yes' rv = self.app.post(url_for('member_insert', origin_id=group.id), data=data, follow_redirects=True) assert b'Ripley' in rv.data # Update with app.test_request_context(): app.preprocess_request() link_id = LinkMapper.get_links(group.id, 'P107')[0].id rv = self.app.get( url_for('member_update', id_=link_id, origin_id=group.id)) assert b'Ripley' in rv.data rv = self.app.post( url_for('member_update', id_=link_id, origin_id=group.id), data={'description': 'We are here to help you.'}, follow_redirects=True) assert b'here to help' in rv.data
def file_view(id_, unlink_id=None): file = EntityMapper.get_by_id(id_) if unlink_id: LinkMapper.delete_by_id(unlink_id) flash(_('link removed'), 'info') path = get_file_path(file.id) tables = {'info': get_entity_data(file)} for name in [ 'source', 'event', 'actor', 'place', 'feature', 'stratigraphic-unit', 'find', 'reference' ]: header = app.config['TABLE_HEADERS'][name] + (['page'] if name == 'reference' else []) tables[name] = {'id': name, 'data': [], 'header': header} for link_ in file.get_links('P67'): view_name = get_view_name(link_.range) view_name = view_name if view_name != 'place' else link_.range.system_type.replace( ' ', '-') data = get_base_table_data(link_.range) if is_authorized('editor'): unlink_url = url_for('file_view', id_=file.id, unlink_id=link_.id) + '#tab-' + view_name data.append(display_remove_link(unlink_url, link_.range.name)) tables[view_name]['data'].append(data) for link_ in file.get_links('P67', True): data = get_base_table_data(link_.domain) data.append(link_.description) if is_authorized('editor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=file.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') unlink_url = url_for('file_view', id_=file.id, unlink_id=link_.id) + '#tab-reference' data.append(display_remove_link(unlink_url, link_.domain.name)) tables['reference']['data'].append(data) return render_template( 'file/view.html', missing_file=False if path else True, entity=file, tables=tables, preview=True if path and preview_file(path) else False, filename=os.path.basename(path) if path else False)
def get_invalid_link_dates() -> list: """ Search for links with invalid date combinations, e.g. begin after end""" from openatlas.models.link import LinkMapper sql = """ SELECT id FROM model.link WHERE begin_from > begin_to OR end_from > end_to OR (begin_from IS NOT NULL AND end_from IS NOT NULL AND begin_from > end_from) OR (begin_to IS NOT NULL AND end_to IS NOT NULL AND begin_to > end_to);""" g.execute(sql) return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
def get_invalid_link_dates(): """ Search for links with invalid date combinations, e.g. begin after end""" from openatlas.models.link import LinkMapper sql = """ SELECT id FROM model.link WHERE begin_from > begin_to OR end_from > end_to OR (begin_from IS NOT NULL AND end_from IS NOT NULL AND begin_from > end_from) OR (begin_to IS NOT NULL AND end_to IS NOT NULL AND begin_to > end_to);""" g.cursor.execute(sql) debug_model['div sql'] += 1 return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
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 search(term, codes, description=False, own=False): sql = EntityMapper.sql if own: sql += " LEFT JOIN web.user_log ul ON e.id = ul.entity_id " sql += " WHERE LOWER(e.name) LIKE LOWER(%(term)s)" sql += " OR lower(e.description) LIKE lower(%(term)s) AND " if description else " AND " sql += " ul.user_id = %(user_id)s AND " if own else '' sql += " e.class_code IN %(codes)s" sql += " GROUP BY e.id ORDER BY e.name" g.cursor.execute(sql, {'term': '%' + term + '%', 'codes': tuple(codes), 'user_id': current_user.id}) debug_model['div sql'] += 1 entities = [] for row in g.cursor.fetchall(): if row.class_code == 'E82': # If found in actor alias entities.append(LinkMapper.get_linked_entity(row.id, 'P131', True)) elif row.class_code == 'E41': # If found in place alias entities.append(LinkMapper.get_linked_entity(row.id, 'P1', True)) else: entities.append(Entity(row)) return entities
def link_string(self, code: str, range_: str, description: Optional[str] = None, inverse: bool = False) -> List[int]: # range_ string from a form, can be empty, an int or an int list presentation # e.g. '', '1', '[]', '[1, 2]' ids = ast.literal_eval(range_) ids = [int(id_) for id_ in ids] if isinstance(ids, list) else [int(ids)] return LinkMapper.insert(self, code, EntityMapper.get_by_ids(ids), description, inverse)
def admin_check_links(check=None): table = None if check: table = { 'id': 'check', 'header': ['domain', 'property', 'range'], 'data': [] } for result in LinkMapper.check_links(): # pragma: no cover table['data'].append( [result['domain'], result['property'], result['range']]) return render_template('admin/check_links.html', table=table)
def source_view(id_, unlink_id=None): source = EntityMapper.get_by_id(id_) if unlink_id: LinkMapper.delete_by_id(unlink_id) flash(_('link removed'), 'info') tables = { 'info': get_entity_data(source), 'text': {'id': 'translation', 'data': [], 'header': ['text', 'type', 'content']}, 'file': {'id': 'files', 'data': [], 'header': app.config['TABLE_HEADERS']['file']}, 'reference': { 'id': 'source', 'data': [], 'header': app.config['TABLE_HEADERS']['reference'] + ['page']}} for text in source.get_linked_entities('P73'): tables['text']['data'].append([ link(text), next(iter(text.nodes)).name if text.nodes else '', truncate_string(text.description)]) for name in ['actor', 'event', 'place', 'feature', 'stratigraphic-unit', 'find']: tables[name] = {'id': name, 'header': app.config['TABLE_HEADERS'][name], 'data': []} for link_ in source.get_links('P67'): data = get_base_table_data(link_.range) view_name = get_view_name(link_.range) view_name = view_name if view_name != 'place' else link_.range.system_type.replace(' ', '-') if is_authorized('editor'): unlink = url_for('source_view', id_=source.id, unlink_id=link_.id) + '#tab-' + view_name data.append(display_remove_link(unlink, link_.range.name)) tables[view_name]['data'].append(data) for link_ in source.get_links(['P67', 'P128'], True): data = get_base_table_data(link_.domain) view_name = get_view_name(link_.domain) if view_name not in ['file']: data.append(link_.description) if is_authorized('editor'): update_url = url_for('reference_link_update', link_id=link_.id, origin_id=source.id) data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>') if is_authorized('editor'): unlink = url_for('source_view', id_=source.id, unlink_id=link_.id) + '#tab-' + view_name data.append(display_remove_link(unlink, link_.domain.name)) tables[view_name]['data'].append(data) return render_template('source/view.html', source=source, tables=tables)
def involvement_update(id_: int, origin_id: int) -> str: link_ = LinkMapper.get_by_id(id_) event = EntityMapper.get_by_id(link_.domain.id) actor = EntityMapper.get_by_id(link_.range.id) origin = event if origin_id == event.id else actor form = build_form(ActorForm, 'Involvement', link_, request) form.save.label.text = _('save') del form.actor, form.event, form.insert_and_continue form.activity.choices = [('P11', g.properties['P11'].name)] if event.class_.code in ['E7', 'E8']: form.activity.choices.append(('P14', g.properties['P14'].name)) if event.class_.code == 'E8': form.activity.choices.append(('P22', g.properties['P22'].name)) form.activity.choices.append(('P23', g.properties['P23'].name)) if form.validate_on_submit(): g.cursor.execute('BEGIN') try: link_.delete() link_ = LinkMapper.get_by_id( event.link(form.activity.data, actor, form.description.data)) link_.set_dates(form) link_.type = get_link_type(form) link_.update() g.cursor.execute('COMMIT') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') tab = 'actor' if origin.view_name == 'event' else 'event' return redirect( url_for(origin.view_name + '_view', id_=origin.id) + '#tab-' + tab) form.activity.data = link_.property.code form.description.data = link_.description form.populate_dates(link_) return render_template( 'involvement/update.html', origin=origin, form=form, linked_object=event if origin_id != event.id else actor)
def test_member(self): with app.app_context(): self.login() with app.test_request_context(): app.preprocess_request() actor_id = EntityMapper.insert('E21', 'Ripley').id group_id = EntityMapper.insert('E74', 'Space Marines').id # Add membership rv = self.app.get(url_for('member_insert', origin_id=group_id)) assert b'Actor Function' in rv.data data = {'group': '[' + str(group_id) + ']'} rv = self.app.post( url_for('membership_insert', origin_id=actor_id), data=data, follow_redirects=True) assert b'Space Marines' in rv.data data = {'group': '[' + str(group_id) + ']', 'continue_': 'yes'} rv = self.app.post( url_for('membership_insert', origin_id=actor_id), data=data, follow_redirects=True) assert b'Space Marines' in rv.data rv = self.app.post( url_for('membership_insert', origin_id=group_id), data=data, follow_redirects=True) assert b"Can't link to itself" in rv.data rv = self.app.post(url_for('member_insert', origin_id=actor_id), data={'actor': '[' + str(actor_id) + ']'}, follow_redirects=True) assert b"Can't link to itself" in rv.data # Add member to group data = {'actor': '[' + str(actor_id) + ']'} rv = self.app.post( url_for('member_insert', origin_id=group_id), data=data, follow_redirects=True) assert b'Ripley' in rv.data data['continue_'] = 'yes' rv = self.app.post( url_for('member_insert', origin_id=group_id), data=data, follow_redirects=True) assert b'Ripley' in rv.data # Update with app.test_request_context(): app.preprocess_request() link_id = LinkMapper.get_links(group_id, 'P107')[0].id rv = self.app.get(url_for('member_update', id_=link_id, origin_id=group_id)) assert b'Ripley' in rv.data rv = self.app.post( url_for('member_update', id_=link_id, origin_id=group_id), data={'description': 'We are here to help you.'}, follow_redirects=True) assert b'here to help' in rv.data
def save(form, event=None, code=None, origin=None): g.cursor.execute('BEGIN') try: log_action = 'insert' if event: log_action = 'update' event.delete_links(['P117', 'P7', 'P24']) else: event = EntityMapper.insert(code, form.name.data) event.name = form.name.data event.description = form.description.data event.update() event.save_dates(form) event.save_nodes(form) if form.event.data: entity = EntityMapper.get_by_id(form.event.data) event.link('P117', entity) if form.place.data: place = LinkMapper.get_linked_entity(int(form.place.data), 'P53') event.link('P7', place) if event.class_.code == 'E8' and form.given_place.data: # Link place for acquisition places = [EntityMapper.get_by_id(i) for i in ast.literal_eval(form.given_place.data)] event.link('P24', places) url = url_for('event_view', id_=event.id) if origin: url = url_for(origin.view_name + '_view', id_=origin.id) + '#tab-event' if origin.view_name == 'reference': link_id = origin.link('P67', event) url = url_for('reference_link_update', link_id=link_id, origin_id=origin.id) elif origin.view_name == 'source': origin.link('P67', event) elif origin.view_name == 'actor': link_id = event.link('P11', origin) url = url_for('involvement_update', id_=link_id, origin_id=origin.id) elif origin.view_name == 'file': origin.link('P67', event) if form.continue_.data == 'yes': url = url_for('event_insert', code=code, origin_id=origin.id if origin else None) g.cursor.execute('COMMIT') logger.log_user(event.id, log_action) flash(_('entity created') if log_action == 'insert' else _('info update'), 'info') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') url = url_for('event_index') return url
def reference_link_update(link_id, origin_id): link_ = LinkMapper.get_by_id(link_id) origin = EntityMapper.get_by_id(origin_id) form = AddReferenceForm() form.save.label.text = _('save') del form.reference if form.validate_on_submit(): link_.description = form.page.data link_.update() flash(_('info update'), 'info') tab = '#tab-reference' if origin.view_name == 'reference': tab = '#tab-' + link_.range.view_name return redirect(url_for(origin.view_name + '_view', id_=origin.id) + tab) form.page.data = link_.description linked_object = link_.domain if link_.domain.id != origin.id else link_.range return render_template('reference/link-update.html', origin=origin, form=form, linked_object=linked_object)
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 test_dates(self) -> None: self.login() with app.app_context(): with app.test_request_context(): app.preprocess_request() # Create invalid dates for an actor and a relation link person = EntityMapper.insert('E21', 'Person') event = EntityMapper.insert('E7', 'Event') person.begin_from = '2018-01-31' person.begin_to = '2018-01-01' person.update() involvement = LinkMapper.get_by_id(event.link('P11', person)) involvement.begin_from = '2017-01-31' involvement.begin_to = '2017-01-01' involvement.end_from = '2017-01-01' involvement.update() rv = self.app.get(url_for('admin_check_dates')) assert b'Invalid dates <span class="tab-counter">1' in rv.data assert b'Invalid link dates <span class="tab-counter">1' in rv.data assert b'Invalid involvement dates <span class="tab-counter">1' in rv.data
def invalid_involvement_dates() -> list: """ Search invalid event participation dates and return the actors e.g. attending person was born after the event ended""" from openatlas.models.link import LinkMapper sql = """ SELECT l.id FROM model.entity actor JOIN model.link l ON actor.id = l.range_id AND l.property_code IN ('P11', 'P14', 'P22', 'P23') JOIN model.entity event ON l.domain_id = event.id WHERE (actor.begin_from IS NOT NULL AND l.end_from IS NOT NULL AND actor.begin_from > l.end_from) OR (actor.begin_to IS NOT NULL AND l.end_to IS NOT NULL AND actor.begin_to > l.end_to) OR (actor.begin_from IS NOT NULL AND event.end_from IS NOT NULL AND actor.begin_from > event.end_from) OR (actor.begin_to IS NOT NULL AND event.end_to IS NOT NULL AND actor.begin_to > event.end_to);""" g.execute(sql) return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
def reference_link_update(link_id, origin_id): link_ = LinkMapper.get_by_id(link_id) origin = EntityMapper.get_by_id(origin_id) view_name = get_view_name(origin) form = AddReferenceForm() form.save.label.text = _('save') del form.reference if form.validate_on_submit(): link_.description = form.page.data link_.update() flash(_('info update'), 'info') tab = '#tab-' + get_view_name( link_.range) if view_name == 'reference' else '#tab-reference' return redirect(url_for(view_name + '_view', id_=origin.id) + tab) form.page.data = link_.description return render_template('reference/link-update.html', origin=origin, linked_object=link_.domain if link_.domain.id != origin.id else link_.range, form=form, class_name=view_name)
def place_delete(id_): entity = EntityMapper.get_by_id(id_) if entity.get_linked_entities('P46'): flash(_('Deletion not possible if subunits exists'), 'error') return redirect(url_for('place_view', id_=id_)) system_type = entity.system_type parent = None if system_type == 'place' else LinkMapper.get_linked_entity(id_, 'P46', True) g.cursor.execute('BEGIN') try: EntityMapper.delete(id_) logger.log_user(id_, 'delete') g.cursor.execute('COMMIT') except Exception as e: # pragma: no cover g.cursor.execute('ROLLBACK') logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') flash(_('entity deleted'), 'info') url = url_for('place_index') if parent: url = url_for('place_view', id_=parent.id) + '#tab-' + system_type return redirect(url)
def node_view(id_: int) -> str: from openatlas.models.link import LinkMapper node = g.nodes[id_] root = g.nodes[node.root[-1]] if node.root else None super_ = g.nodes[node.root[0]] if node.root else None header = [_('name'), _('class'), _('info')] if root and root.value_type: # pragma: no cover header = [_('name'), _('value'), _('class'), _('info')] tables = {'info': get_entity_data(node), 'entities': Table(header)} for entity in node.get_linked_entities(['P2', 'P89'], inverse=True, nodes=True): # If it is a place location get the corresponding object entity = entity if node.class_.code == 'E55' else entity.get_linked_entity( 'P53', True) if entity: # If not entity it is a place node, so do not add data = [link(entity)] if root and root.value_type: # pragma: no cover data.append(format_number(entity.nodes[node])) data.append(g.classes[entity.class_.code].name) data.append(truncate_string(entity.description)) tables['entities'].rows.append(data) tables['link_entities'] = Table([_('domain'), _('range')]) for row in LinkMapper.get_entities_by_node(node): tables['link_entities'].rows.append([ link(EntityMapper.get_by_id(row.domain_id)), link(EntityMapper.get_by_id(row.range_id)) ]) tables['subs'] = Table([_('name'), _('count'), _('info')]) for sub_id in node.subs: sub = g.nodes[sub_id] tables['subs'].rows.append( [link(sub), sub.count, truncate_string(sub.description)]) return render_template('types/view.html', node=node, super_=super_, tables=tables, root=root)
def invalid_involvement_dates(): """ Search invalid event participation dates and return the actors e.g. attending person was born after the event ended """ from openatlas.models.link import LinkMapper sql = """ SELECT l.id FROM model.entity actor JOIN model.link l ON actor.id = l.range_id AND l.property_code IN ('P11', 'P14', 'P22', 'P23') JOIN model.entity event ON l.domain_id = event.id WHERE (actor.begin_from IS NOT NULL AND l.end_from IS NOT NULL AND actor.begin_from > l.end_from) OR (actor.begin_to IS NOT NULL AND l.end_to IS NOT NULL AND actor.begin_to > l.end_to) OR (actor.begin_from IS NOT NULL AND event.end_from IS NOT NULL AND actor.begin_from > event.end_from) OR (actor.begin_to IS NOT NULL AND event.end_to IS NOT NULL AND actor.begin_to > event.end_to);""" g.cursor.execute(sql) debug_model['div sql'] += 1 return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
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_linked_entities(self, code, inverse: Optional[bool] = False, nodes: Optional[bool] = False): return LinkMapper.get_linked_entities(self, code, inverse=inverse, nodes=nodes)
def get_links(self, code, inverse=False): return LinkMapper.get_links(self, code, inverse)
def delete_links(self, codes) -> None: LinkMapper.delete_by_codes(self, codes)
def get_links(self, code, inverse: Optional[bool] = False): return LinkMapper.get_links(self, code, inverse)
def link(self, code, range_, description: Optional[str] = None, inverse: Optional[bool] = False): return LinkMapper.insert(self, code, range_, description, inverse)
def link_delete(id_, origin_id): LinkMapper.delete(id_) flash(_('link removed'), 'info') origin = EntityMapper.get_by_id(origin_id) return redirect(url_for(origin.view_name + '_view', id_=origin.id))
def link(self, code, range_, description=None, inverse=False): return LinkMapper.insert(self, code, range_, description, inverse)
def get_linked_entities(self, code, inverse=False): return LinkMapper.get_linked_entities(self, code, inverse)
def search(form): if not form.term.data: return [] sql = EntityMapper.build_sql() + """ {user_clause} WHERE (LOWER(e.name) LIKE LOWER(%(term)s) {description_clause}) AND {user_clause2} (""".format( user_clause=""" LEFT JOIN web.user_log ul ON e.id = ul.entity_id """ if form.own.data else '', description_clause=""" OR lower(e.description) LIKE lower(%(term)s) """ if form.desc.data else '', user_clause2=' ul.user_id = %(user_id)s AND ' if form.own.data else '') sql_where = [] for name in form.classes.data: if name in ['source', 'event']: sql_where.append("e.class_code IN ({codes})".format( codes=str(app.config['CLASS_CODES'][name])[1:-1])) elif name == 'actor': codes = app.config['CLASS_CODES'][name] + ['E82'] # Add alias sql_where.append(" e.class_code IN ({codes})".format(codes=str(codes)[1:-1])) elif name == 'place': sql_where.append("(e.class_code = 'E41' OR e.system_type = 'place')") elif name == 'feature': sql_where.append("e.system_type = 'feature'") elif name == 'stratigraphic unit': sql_where.append("e.system_type = 'stratigraphic unit'") elif name == 'find': sql_where.append("e.class_code = 'E22'") elif name == 'reference': sql_where.append(" e.class_code IN ({codes}) AND e.system_type != 'file'".format( codes=str(app.config['CLASS_CODES']['reference'])[1:-1])) elif name == 'file': sql_where.append(" e.system_type = 'file'") sql += ' OR '.join(sql_where) + ") GROUP BY e.id ORDER BY e.name;" g.cursor.execute(sql, {'term': '%' + form.term.data + '%', 'user_id': current_user.id}) debug_model['div sql'] += 1 # Prepare date filter from_date = DateMapper.form_to_datetime64(form.begin_year.data, form.begin_month.data, form.begin_day.data) to_date = DateMapper.form_to_datetime64(form.end_year.data, form.end_month.data, form.end_day.data, True) # Refill form in case dates were completed if from_date: string = str(from_date) if string.startswith('-') or string.startswith('0000'): string = string[1:] parts = string.split('-') form.begin_month.raw_data = None form.begin_day.raw_data = None form.begin_month.data = int(parts[1]) form.begin_day.data = int(parts[2]) if to_date: string = str(to_date) if string.startswith('-') or string.startswith('0000'): string = string[1:] # pragma: no cover parts = string.split('-') form.end_month.raw_data = None form.end_day.raw_data = None form.end_month.data = int(parts[1]) form.end_day.data = int(parts[2]) entities = [] for row in g.cursor.fetchall(): entity = None if row.class_code == 'E82': # If found in actor alias entity = LinkMapper.get_linked_entity(row.id, 'P131', True) elif row.class_code == 'E41': # If found in place alias entity = LinkMapper.get_linked_entity(row.id, 'P1', True) elif row.class_code == 'E18': if row.system_type in form.classes.data: entity = Entity(row) else: entity = Entity(row) if not entity: # pragma: no cover continue if not from_date and not to_date: entities.append(entity) continue # Date criteria present but entity has no dates if not entity.begin_from and not entity.begin_to and not entity.end_from \ and not entity.end_to: if form.include_dateless.data: # Include dateless entities entities.append(entity) continue # Check date criteria dates = [entity.begin_from, entity.begin_to, entity.end_from, entity.end_to] begin_check_ok = False if not from_date: begin_check_ok = True # pragma: no cover else: for date in dates: if date and date >= from_date: begin_check_ok = True end_check_ok = False if not to_date: end_check_ok = True # pragma: no cover else: for date in dates: if date and date <= to_date: end_check_ok = True if begin_check_ok and end_check_ok: entities.append(entity) return {d.id: d for d in entities}.values() # Remove duplicates before returning