def add_tabs_for_type(entity: Type) -> dict[str, Tab]: tabs = { 'subs': Tab('subs', entity=entity), 'entities': Tab('entities', entity=entity)} for sub_id in entity.subs: sub = g.types[sub_id] tabs['subs'].table.rows.append([ link(sub), sub.count, sub.description]) if entity.category == 'value': tabs['entities'].table.header = \ [_('name'), _('value'), _('class'), _('info')] for item in entity.get_linked_entities( ['P2', 'P89'], inverse=True, types=True): if item.class_.name in ['location', 'reference_system']: continue # pragma: no cover if item.class_.name == 'object_location': item = item.get_linked_entity_safe('P53', inverse=True) data = [link(item)] if entity.category == 'value': data.append(format_number(item.types[entity])) data.append(item.class_.label) data.append(item.description) tabs['entities'].table.rows.append(data) if not tabs['entities'].table.rows: # If no entities available get links with this type_id tabs['entities'].table.header = [_('domain'), _('range')] for row in Link.get_links_by_type(entity): tabs['entities'].table.rows.append([ link(Entity.get_by_id(row['domain_id'])), link(Entity.get_by_id(row['range_id']))]) return tabs
def __init__(self, row: dict[str, Any], domain: Optional[Entity] = None, range_: Optional[Entity] = None) -> None: from openatlas.models.entity import Entity from openatlas.util.util import format_date_part self.id = row['id'] self.description = row['description'] self.property = g.properties[row['property_code']] self.domain = domain if domain else Entity.get_by_id(row['domain_id']) self.range = range_ if range_ else Entity.get_by_id(row['range_id']) self.type = g.types[row['type_id']] if row['type_id'] else None self.types: dict[Entity, None] = {} if 'type_id' in row and row['type_id']: self.types[g.types[row['type_id']]] = None if 'begin_from' in row: self.begin_from = timestamp_to_datetime64(row['begin_from']) self.begin_to = timestamp_to_datetime64(row['begin_to']) self.begin_comment = row['begin_comment'] self.end_from = timestamp_to_datetime64(row['end_from']) self.end_to = timestamp_to_datetime64(row['end_to']) self.end_comment = row['end_comment'] self.first = format_date_part(self.begin_from, 'year') \ if self.begin_from else None self.last = format_date_part(self.end_from, 'year') \ if self.end_from else None self.last = format_date_part(self.end_to, 'year') \ if self.end_to else self.last
def overlay_update(id_: int) -> Union[str, Response]: overlay = Overlay.get_by_id(id_) form = OverlayForm() if form.validate_on_submit(): Overlay.update(form=form, image_id=overlay.image_id, place_id=overlay.place_id) flash(_('info update'), 'info') return redirect( f"{url_for('entity_view', id_=overlay.place_id)}#tab-file") bounding = ast.literal_eval(overlay.bounding_box) if len(bounding) == 2: # pragma no cover bounding = [[0, 0], [0, 0], [0, 0]] # For data entered before 6.4.0 form.top_left_easting.data = bounding[0][1] form.top_left_northing.data = bounding[0][0] form.top_right_easting.data = bounding[1][1] form.top_right_northing.data = bounding[1][0] form.bottom_left_easting.data = bounding[2][1] form.bottom_left_northing.data = bounding[2][0] entity = Entity.get_by_id(overlay.place_id) return render_template( 'overlay.html', form=form, overlay=overlay, entity=entity, buttons=[ button(_('remove'), url_for('overlay_remove', id_=overlay.id, place_id=entity.id), onclick=f"return confirm('{uc_first(_('remove'))}?');") ], crumbs=[[_('place'), url_for('index', view='place')], entity, Entity.get_by_id(overlay.image_id), _('update overlay')])
def get_invalid_cidoc_links() -> list[dict[str, str]]: from openatlas.models.entity import Entity from openatlas.util.util import link invalid_linking = [] for row in Db.get_cidoc_links(): property_ = g.properties[row['property_code']] domain_is_valid = property_.find_object('domain_class_code', row['domain_code']) range_is_valid = property_.find_object('range_class_code', row['range_code']) if not domain_is_valid or not range_is_valid: invalid_linking.append(row) invalid_links = [] for item in invalid_linking: for row in Db.get_invalid_links(item): domain = Entity.get_by_id(row['domain_id']) range_ = Entity.get_by_id(row['range_id']) invalid_links.append({ 'domain': f"{link(domain)} ({domain.cidoc_class.code})", 'property': link(g.properties[row['property_code']]), 'range': f"{link(range_)} ({range_.cidoc_class.code})" }) return invalid_links
def build_move_form(node: Node) -> FlaskForm: class Form(FlaskForm): # type: ignore is_node_form = HiddenField() checkbox_values = HiddenField() selection = SelectMultipleField( '', [InputRequired()], coerce=int, option_widget=widgets.CheckboxInput(), widget=widgets.ListWidget(prefix_label=False)) save = SubmitField(uc_first(_('move entities'))) root = g.nodes[node.root[-1]] setattr(Form, str(root.id), TreeField(str(root.id))) form = Form(obj=node) choices = [] if root.class_.name == 'administrative_unit': 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 Link.get_entities_by_node(node): domain = Entity.get_by_id(row['domain_id']) range_ = Entity.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.selection.choices = choices return form
def check_links() -> List[Dict[str, str]]: """ Check all existing links for CIDOC CRM validity and return the invalid ones.""" from openatlas.util.display import link from openatlas.models.entity import Entity invalid_links = [] for row in Db.get_cidoc_links(): property_ = g.properties[row['property']] domain_is_valid = property_.find_object('domain_class_code', row['domain']) range_is_valid = property_.find_object('range_class_code', row['range']) invalid_linking = [] if not domain_is_valid or not range_is_valid: invalid_linking.append(row) for item in invalid_linking: for row2 in Db.get_invalid_links(item): domain = Entity.get_by_id(row2['domain_id']) range_ = Entity.get_by_id(row2['range_id']) invalid_links.append({ 'domain': link(domain) + ' (' + domain.cidoc_class.code + ')', 'property': link(g.properties[row2['property_code']]), 'range': link(range_) + ' (' + range_.cidoc_class.code + ')' }) return invalid_links
def member_update(id_: int, origin_id: int) -> Union[str, Response]: link_ = Link.get_by_id(id_) domain = Entity.get_by_id(link_.domain.id) range_ = Entity.get_by_id(link_.range.id) origin = range_ if origin_id == range_.id else domain form = build_form('actor_function', link_) if form.validate_on_submit(): Transaction.begin() try: link_.delete() link_ = Link.get_by_id( domain.link('P107', range_, form.description.data)[0]) link_.set_dates(process_form_dates(form)) link_.type = get_link_type(form) link_.update() Transaction.commit() except Exception as e: # pragma: no cover Transaction.rollback() logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') return redirect( f"{url_for('view', id_=origin.id)}" f"#tab-member{'-of' if origin.id == range_.id else ''}") form.save.label.text = _('save') related = range_ if origin_id == domain.id else domain return render_template( 'display_form.html', form=form, crumbs=[[_('actor'), url_for('index', view='actor')], origin, related, _('edit')])
def link_update(id_: int, origin_id: int) -> Union[str, Response]: link_ = Link.get_by_id(id_) domain = Entity.get_by_id(link_.domain.id) range_ = Entity.get_by_id(link_.range.id) origin = Entity.get_by_id(origin_id) if 'reference' in [domain.class_.view, range_.class_.view]: return reference_link_update(link_, origin) if 'event' in [domain.class_.view, range_.class_.view]: return involvement_update(link_, origin) if domain.class_.view == 'actor' and range_.class_.view == 'actor': return relation_update(link_, domain, range_, origin) abort(403) # pragma: no cover
def admin_check_link_duplicates( delete: Optional[str] = None) -> Union[str, Response]: if delete: count = Link.delete_link_duplicates() logger.log('info', 'admin', f"Deleted duplicate links: {count}") flash(f"{_('deleted links')}: {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 row in Link.check_link_duplicates(): table.rows.append([ link(Entity.get_by_id(row['domain_id'])), link(Entity.get_by_id(row['range_id'])), link(g.properties[row['property_code']]), row['description'], link(g.types[row['type_id']]) if row['type_id'] else '', format_date(row['begin_from']), format_date(row['begin_to']), row['begin_comment'], format_date(row['end_from']), format_date(row['end_to']), row['end_comment'], row['count']]) if not table.rows: # Check single types for multiple use table = Table( ['entity', 'class', 'base type', 'incorrect multiple types']) for row in Link.check_single_type_duplicates(): remove_links = [] for type_ in row['offending_types']: url = url_for( 'admin_delete_single_type_duplicate', entity_id=row['entity'].id, type_id=type_.id) remove_links.append( f'<a href="{url}">{uc_first(_("remove"))}</a>' f'{type_.name}') table.rows.append([ link(row['entity']), row['entity'].class_.name, link(g.types[row['type'].id]), '<br><br><br><br><br>'.join(remove_links)]) return render_template( 'admin/check_link_duplicates.html', table=table, title=_('admin'), crumbs=[ [_('admin'), f"{url_for('admin_index')}#tab-data"], _('check link duplicates')])
def sex(id_: int) -> Union[str, Response]: entity = Entity.get_by_id(id_, types=True) buttons = [manual('tools/anthropological_analyses')] if is_authorized('contributor'): buttons.append(button(_('edit'), url_for('sex_update', id_=entity.id))) data = [] for item in SexEstimation.get_types(entity): type_ = g.types[item['id']] feature = SexEstimation.features[type_.name] data.append({ 'name': type_.name, 'category': feature['category'], 'feature_value': feature['value'], 'option_value': SexEstimation.options[item['description']], 'value': item['description'] }) return render_template('anthropology/sex.html', entity=entity, buttons=buttons, data=data, result=print_result(entity), crumbs=[ entity, [ _('anthropological analyses'), url_for('anthropology_index', id_=entity.id) ], _('sex estimation') ])
def check_single_type_duplicates() -> List[List[str]]: from openatlas.models.node import Node from openatlas.models.entity import Entity data = [] for node in g.nodes.values(): if node.root or node.multiple or node.value_type: continue # pragma: no cover node_ids = Node.get_all_sub_ids(node) if not node_ids: continue # pragma: no cover for id_ in Db.check_single_type_duplicates(node_ids): offending_nodes = [] entity = Entity.get_by_id(id_, nodes=True) for entity_node in entity.nodes: if g.nodes[entity_node.root[-1]].id != node.id: continue # pragma: no cover offending_nodes.append( '<a href="{url}">{label}</a> {name}'.format( label=uc_first(_('remove')), name=entity_node.name, url=url_for('admin_delete_single_type_duplicate', entity_id=entity.id, node_id=entity_node.id))) data.append([ link(entity), entity.class_.name, link(g.nodes[node.id]), '<br><br><br><br><br>'.join(offending_nodes) ]) return data
def overlay_insert(image_id: int, place_id: int, link_id: int) -> Union[str, Response]: form = OverlayForm() if form.validate_on_submit(): Overlay.insert(form=form, image_id=image_id, place_id=place_id, link_id=link_id) return redirect(f"{url_for('entity_view', id_=place_id)}#tab-file") return render_template( 'overlay.html', form=form, crumbs=[[_('place'), url_for('index', view='place')], Entity.get_by_id(place_id), Entity.get_by_id(image_id), _('overlay')])
def note_view(id_: int) -> str: note = User.get_note_by_id(id_) if not note['public'] and note['user_id'] != current_user.id: abort(403) # pragma: no cover entity = Entity.get_by_id(note['entity_id']) buttons: list[str] = [manual('tools/notes')] if note['user_id'] == current_user.id: buttons += [ button(_('edit'), url_for('note_update', id_=note['id'])), button(_('delete'), url_for('note_delete', id_=note['id'])) ] elif is_authorized('manager'): # pragma: no cover buttons += [ button(_('set private'), url_for('note_set_private', id_=note['id'])) ] tabs = { 'info': Tab('info', buttons=buttons, content=f"<h1>{uc_first(_('note'))}</h1>{note['text']}") } return render_template('tabs.html', tabs=tabs, entity=entity, crumbs=[[ _(entity.class_.view), url_for('index', view=entity.class_.view) ], link(entity), _('note')])
def reference_add(id_: int, view: str) -> Union[str, Response]: reference = Entity.get_by_id(id_) form = build_add_reference_form(view) if form.validate_on_submit(): entity = Entity.get_by_id(getattr(form, view).data) reference.link('P67', entity, form.page.data) return redirect(f"{url_for('view', id_=reference.id)}#tab-{view}") if reference.class_.name == 'external_reference': form.page.label.text = uc_first(_('link text')) return render_template( 'display_form.html', form=form, title=_('reference'), crumbs=[[_('reference'), url_for('index', view='reference')], reference, _('link')])
def relation_insert(origin_id: int) -> Union[str, Response]: origin = Entity.get_by_id(origin_id) form = build_form('actor_actor_relation') form.relation_origin_id.data = origin.id if form.validate_on_submit(): Transaction.begin() try: for actor in Entity.get_by_ids(ast.literal_eval(form.actor.data)): if form.inverse.data: link_ = Link.get_by_id( actor.link('OA7', origin, form.description.data)[0]) else: link_ = Link.get_by_id( origin.link('OA7', actor, form.description.data)[0]) link_.set_dates(form) link_.type = get_link_type(form) link_.update() Transaction.commit() flash(_('entity created'), 'info') except Exception as e: # pragma: no cover Transaction.rollback() logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') if hasattr(form, 'continue_') and form.continue_.data == 'yes': return redirect(url_for('relation_insert', origin_id=origin_id)) return redirect( url_for('entity_view', id_=origin.id) + '#tab-relation') return render_template( 'display_form.html', form=form, title=_('relation'), crumbs=[[_('actor'), url_for('index', view='actor')], origin, '+ ' + uc_first(_('relation'))])
def delete_entity(id_: int) -> Optional[str]: url = None entity = Entity.get_by_id(id_) if not is_authorized(entity.class_.write_access): abort(403) # pragma: no cover if isinstance(entity, ReferenceSystem): if entity.system: abort(403) if entity.forms: flash(_('Deletion not possible if forms are attached'), 'error') return url_for('entity_view', id_=id_) if entity.class_.view in ['artifact', 'place']: if entity.get_linked_entities('P46'): flash(_('Deletion not possible if subunits exists'), 'error') return url_for('entity_view', id_=id_) parent = None \ if entity.class_.name == 'place' \ else entity.get_linked_entity('P46', True) entity.delete() logger.log_user(id_, 'delete') flash(_('entity deleted'), 'info') if parent: tab = f"#tab-{entity.class_.name.replace('_', '-')}" url = url_for('entity_view', id_=parent.id) + tab else: Entity.delete_(id_) logger.log_user(id_, 'delete') flash(_('entity deleted'), 'info') if entity.class_.name == 'file': try: delete_files(id_) except Exception as e: # pragma: no cover logger.log('error', 'file', 'file deletion failed', e) flash(_('error file delete'), 'error') return url
def link_insert(id_: int, view: str) -> Union[str, Response]: entity = Entity.get_by_id(id_) property_code = 'P67' inverse = False if entity.class_.view == 'actor' and view == 'artifact': property_code = 'P52' inverse = True if request.method == 'POST': if request.form['checkbox_values']: entity.link_string(property_code, request.form['checkbox_values'], inverse=inverse) return redirect(f"{url_for('view', id_=entity.id)}#tab-{view}") if entity.class_.view == 'actor' and view == 'artifact': excluded = Entity.get_by_link_property(property_code, 'artifact') else: excluded = entity.get_linked_entities(property_code, inverse=inverse) return render_template('form.html', form=build_table_form(view, excluded), title=_(entity.class_.view), crumbs=[[ _(entity.class_.view), url_for('index', view=entity.class_.view) ], entity, _('link')])
def update(id_: int) -> Union[str, Response]: entity = Entity.get_by_id(id_, types=True, aliases=True) check_update_access(entity) if entity.check_for_too_many_links_for_single_type(): abort(422) place_info = get_place_info_for_update(entity) form = build_form(entity.class_.name, entity, location=place_info['location']) if form.validate_on_submit(): if isinstance(entity, Type) and not check_type(entity, form): return redirect(url_for('view', id_=entity.id)) if was_modified(form, entity): # pragma: no cover del form.save flash(_('error modified'), 'error') return render_template( 'entity/update.html', form=form, entity=entity, modifier=link(logger.get_log_info(entity.id)['modifier'])) return redirect(save(form, entity)) populate_update_form(form, entity) if entity.class_.view in ['artifact', 'place']: entity.set_image_for_places() return render_template( 'entity/update.html', form=form, entity=entity, gis_data=place_info['gis_data'], overlays=place_info['overlays'], geonames_module=check_geonames_module(entity.class_.name), title=entity.name, crumbs=add_crumbs(entity.class_.name, entity, place_info['structure']))
def reference_link_update(link_: Link, origin: Entity) -> Union[str, Response]: origin = Entity.get_by_id(origin.id) form = AddReferenceForm() del form.reference if form.validate_on_submit(): link_.description = form.page.data link_.update() flash(_('info update'), 'info') tab = link_.range.class_.view if origin.class_.view == 'reference' \ else 'reference' return redirect(f"{url_for('view', id_=origin.id)}#tab-{tab}") form.save.label.text = _('save') form.page.data = link_.description if link_.domain.class_.name == 'external_reference': form.page.label.text = uc_first(_('link text')) return render_template( 'display_form.html', form=form, crumbs=[ [_(origin.class_.view), url_for('index', view=origin.class_.view)], origin, link_.domain if link_.domain.id != origin.id else link_.range, _('edit')])
def user_activity(user_id: int = 0) -> str: form = ActivityForm() form.user.choices = [(0, _('all'))] + User.get_users_for_form() if form.validate_on_submit(): activity = User.get_activities(int(form.limit.data), int(form.user.data), form.action.data) elif user_id: form.user.data = user_id activity = User.get_activities(100, user_id, 'all') else: activity = User.get_activities(100, 0, 'all') table = Table(['date', 'user', 'action', 'entity'], order=[[0, 'desc']]) for row in activity: try: entity = link(Entity.get_by_id(row['entity_id'])) except AttributeError: # pragma: no cover - entity already deleted entity = f"id {row['entity_id']}" user = User.get_by_id(row['user_id']) table.rows.append([ format_date(row['created']), link(user) if user else f"id {row['user_id']}", _(row['action']), entity ]) return render_template('user/activity.html', table=table, form=form, title=_('user'), crumbs=[[_('admin'), url_for('admin_index')], _('activity')])
def insert( class_: str, origin_id: Optional[int] = None) -> Union[str, Response]: check_insert_access(class_) origin = Entity.get_by_id(origin_id) if origin_id else None form = build_form(class_, origin=origin) if form.validate_on_submit(): if class_ == 'file': return redirect(insert_files(form, origin)) return redirect(save(form, class_=class_, origin=origin)) populate_insert_form(form, class_, origin) place_info = get_place_info_for_insert(g.classes[class_].view, origin) return render_template( 'entity/insert.html', form=form, view_name=g.classes[class_].view, gis_data=place_info['gis_data'], geonames_module=check_geonames_module(class_), writable=os.access(app.config['UPLOAD_DIR'], os.W_OK), overlays=place_info['overlays'], title=_(g.classes[class_].view), crumbs=add_crumbs( class_, origin, place_info['structure'], insert_=True))
def update_links(form: FlaskForm, entity: Entity) -> None: for field in form: if field.id.startswith('reference_system_id_'): # Delete and recreate link system = Entity.get_by_id(int(field.id.replace('reference_system_id_', ''))) precision_field = getattr(form, field.id.replace('id_', 'precision_')) Db.remove_link(system.id, entity.id) if field.data: system.link('P67', entity, field.data, type_id=precision_field.data)
def get_subunit_hierarchy(id_: int) -> List[Dict[str, Any]]: try: entity = Entity.get_by_id(id_, nodes=True, aliases=True) except EntityDoesNotExistError: # pragma: no cover raise EntityDoesNotExistError if not entity.class_.name == 'place' and not entity.class_.name == 'feature' \ and not entity.class_.name == 'stratigraphic_unit': raise InvalidSubunitError # pragma: no cover return GetSubunitHierarchy.get_subunits_recursive(entity, [])
def involvement_update(link_: Link, origin: Entity) -> Union[str, Response]: form = build_form('involvement', link_) form.activity.choices = [('P11', g.properties['P11'].name)] event = Entity.get_by_id(link_.domain.id) actor = Entity.get_by_id(link_.range.id) origin = event if origin.id == event.id else actor if event.class_.name in ['acquisition', 'activity']: form.activity.choices.append(('P14', g.properties['P14'].name)) if event.class_.name == 'acquisition': form.activity.choices.append(('P22', g.properties['P22'].name)) form.activity.choices.append(('P23', g.properties['P23'].name)) if form.validate_on_submit(): Transaction.begin() try: link_.delete() link_ = Link.get_by_id( event.link( form.activity.data, actor, form.description.data)[0]) link_.set_dates(process_form_dates(form)) link_.type = get_link_type(form) link_.update() Transaction.commit() except Exception as e: # pragma: no cover Transaction.rollback() logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') return redirect( f"{url_for('view', id_=origin.id)}" f"#tab-{'actor' if origin.class_.view == 'event' else 'event'}") form.save.label.text = _('save') form.activity.data = link_.property.code form.description.data = link_.description return render_template( 'display_form.html', origin=origin, form=form, crumbs=[ [_(origin.class_.view), url_for('index', view=origin.class_.view)], origin, event if origin.id != event.id else actor, _('edit')])
def anthropology_index(id_: int) -> Union[str, Response]: entity = Entity.get_by_id(id_) buttons = [ manual('tools/anthropological_analyses'), button(_('sex estimation'), url_for('sex', id_=entity.id)), print_result(entity) ] return render_template('anthropology/index.html', entity=entity, buttons=buttons, crumbs=[entity, _('anthropological analyses')])
def source_add(id_: int, view: str) -> Union[str, Response]: source = Entity.get_by_id(id_) if request.method == 'POST': if request.form['checkbox_values']: source.link_string('P67', request.form['checkbox_values']) return redirect(f"{url_for('entity_view', id_=source.id)}#tab-{view}") return render_template( 'form.html', form=build_table_form(view, source.get_linked_entities('P67')), title=_('source'), crumbs=[[_('source'), url_for('index', view='source')], source, _('link')])
def admin_check_link_duplicates( delete: Optional[str] = None) -> Union[str, Response]: if delete: count = Link.delete_link_duplicates() logger.log('info', 'admin', f"Deleted duplicate links: {count}") flash(f"{_('deleted links')}: {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 row in Link.check_link_duplicates(): table.rows.append([ link(Entity.get_by_id(row['domain_id'])), link(Entity.get_by_id(row['range_id'])), link(g.properties[row['property_code']]), row['description'], link(g.nodes[row['type_id']]) if row['type_id'] else '', format_date(row['begin_from']), format_date(row['begin_to']), row['begin_comment'], format_date(row['end_from']), format_date(row['end_to']), row['end_comment'], row['count']]) duplicates = False if table.rows: duplicates = True else: # If no exact duplicates check single types for multiple use table = Table( ['entity', 'class', 'base type', 'incorrect multiple types'], rows=Link.check_single_type_duplicates()) return render_template( 'admin/check_link_duplicates.html', table=table, duplicates=duplicates, title=_('admin'), crumbs=[ [_('admin'), f"{url_for('admin_index')}#tab-data"], _('check link duplicates')])
def sex_update(id_: int) -> Union[str, Response]: class Form(FlaskForm): pass entity = Entity.get_by_id(id_, types=True) choices = [(option, option) for option in SexEstimation.options] for feature, values in SexEstimation.features.items(): description = '' if values['female'] or values['male']: description = f"Female: {values['female']}, male: {values['male']}" setattr( Form, feature, SelectField( f"{uc_first(feature.replace('_', ' '))} ({values['category']})", choices=choices, default='Not preserved', description=description)) setattr(Form, 'save', SubmitField(_('save'))) form = Form() types = get_types(entity.id) if form.validate_on_submit(): data = form.data data.pop('save', None) data.pop('csrf_token', None) try: Transaction.begin() SexEstimation.save(entity, data, types) Transaction.commit() except Exception as e: # pragma: no cover Transaction.rollback() logger.log('error', 'database', 'transaction failed', e) flash(_('error transaction'), 'error') return redirect(url_for('sex', id_=entity.id)) # Fill in data for dict_ in types: getattr(form, g.types[dict_['id']].name).data = dict_['description'] return render_template( 'display_form.html', entity=entity, manual_page='tools/anthropological_analyses', form=form, crumbs=[ entity, [ _('anthropological analyses'), url_for('anthropology_index', id_=entity.id) ], [_('sex estimation'), url_for('sex', id_=entity.id)], _('edit') ])
def add_tabs_for_place(entity: Entity) -> dict[str, Tab]: tabs = {'source': Tab('source', entity=entity)} if entity.class_.name == 'place': tabs['event'] = Tab('event', entity=entity) tabs['reference'] = Tab('reference', entity=entity) if entity.class_.name == 'place': tabs['actor'] = Tab('actor', entity=entity) tabs['feature'] = Tab('feature', entity=entity) elif entity.class_.name == 'feature': tabs['stratigraphic_unit'] = Tab( 'stratigraphic_unit', entity=entity) elif entity.class_.name == 'stratigraphic_unit': tabs['artifact'] = Tab('artifact', entity=entity) tabs['human_remains'] = Tab('human_remains', entity=entity) entity.location = entity.get_linked_entity_safe('P53', types=True) events = [] # Collect events to display actors event_ids = [] # Keep track of event ids to prevent event doubles for event in entity.location.get_linked_entities( ['P7', 'P26', 'P27'], inverse=True): events.append(event) tabs['event'].table.rows.append(get_base_table_data(event)) event_ids.append(event.id) for event in entity.get_linked_entities('P24', inverse=True): if event.id not in event_ids: # Don't add again if already in table tabs['event'].table.rows.append(get_base_table_data(event)) events.append(event) if entity.class_.name == 'place': for link_ in entity.location.get_links( ['P74', 'OA8', 'OA9'], inverse=True): actor = Entity.get_by_id(link_.domain.id) tabs['actor'].table.rows.append([ link(actor), g.properties[link_.property.code].name, actor.class_.name, actor.first, actor.last, actor.description]) actor_ids = [] for event in events: for actor in event.get_linked_entities( ['P11', 'P14', 'P22', 'P23']): if actor.id in actor_ids: continue # pragma: no cover actor_ids.append(actor.id) tabs['actor'].table.rows.append([ link(actor), f"{_('participated at an event')}", event.class_.name, '', '', '']) return tabs
def update_system(self, form: FlaskForm) -> None: self.update(form) precision_default_id = None entity_with_updated_nodes = Entity.get_by_id(self.id, nodes=True) if entity_with_updated_nodes.nodes: # Get default precision id if it was set precision_default_id = list(entity_with_updated_nodes.nodes.keys())[0].id Db.update_system({ 'entity_id': self.id, 'name': self.name, 'website_url': self.website_url, 'resolver_url': self.resolver_url, 'identifier_example': self.placeholder, 'precision_default_id': precision_default_id})