def table_select_model(self, name: str, selected=None) -> str: # Todo: extra sortfunction for class and property code e.g. E69 if name in ['domain', 'range']: entities = g.classes else: entities = g.properties table = Table(['code', 'name'], defs='''[{"orderDataType": "cidoc-model", "targets":[0]}, {"sType": "numeric", "targets": [0]}]''' ) for id_ in entities: table.rows.append([ '<a onclick="selectFromTable(this, \'' + name + '\', \'' + str(id_) + '\')">' + entities[id_].code + '</a>', '<a onclick="selectFromTable(this, \'' + name + '\', \'' + str(id_) + '\')">' + entities[id_].name + '</a>' ]) value = selected.code + ' ' + selected.name if selected else '' html = """ <input id="{name}-button" value="{value}" class="table-select" type="text" onfocus="this.blur()" readonly="readonly" /> <div id="{name}-overlay" class="overlay"> <div id="{name}-dialog" class="overlay-container"> {table} </div> </div> <script>$(document).ready(function () {{createOverlay("{name}");}});</script> """.format(name=name, value=value, table=table.display(name)) return html
def admin_check_dates() -> str: # Get invalid date combinations (e.g. begin after end) tables = {'link_dates': Table(['link', 'domain', 'range']), 'involvement_dates': Table(['actor', 'event', 'class', 'involvement', 'description']), 'dates': Table(['name', 'class', 'type', 'system type', 'created', 'updated', 'description'])} for entity in DateMapper.get_invalid_dates(): tables['dates'].rows.append([link(entity), link(entity.class_), entity.print_base_type(), entity.system_type, format_date(entity.created), format_date(entity.modified), truncate_string(entity.description)]) for link_ in DateMapper.get_invalid_link_dates(): label = '' if link_.property.code == 'OA7': # pragma: no cover label = 'relation' elif link_.property.code == 'P107': # pragma: no cover label = 'member' elif link_.property.code in ['P11', 'P14', 'P22', 'P23']: label = 'involvement' url = url_for(label + '_update', id_=link_.id, origin_id=link_.domain.id) tables['link_dates'].rows.append(['<a href="' + url + '">' + uc_first(_(label)) + '</a>', link(link_.domain), link(link_.range)]) for link_ in DateMapper.invalid_involvement_dates(): event = link_.domain actor = link_.range update_url = url_for('involvement_update', id_=link_.id, origin_id=actor.id) data = ([link(actor), link(event), g.classes[event.class_.code].name, link_.type.name if link_.type else '', truncate_string(link_.description), '<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>']) tables['involvement_dates'].rows.append(data) return render_template('admin/check_dates.html', tables=tables)
def object_view(id_: int) -> str: object_ = EntityMapper.get_by_id(id_, nodes=True) object_.note = UserMapper.get_note(object_) tables = { 'info': get_entity_data(object_), 'source': Table(Table.HEADERS['source']), 'event': Table(Table.HEADERS['event']) } for link_ in object_.get_links('P128'): data = get_base_table_data(link_.range) if is_authorized('contributor'): url = url_for('link_delete', id_=link_.id, origin_id=object_.id) data.append( display_remove_link(url + '#tab-' + link_.range.table_name, link_.range.name)) tables['source'].rows.append(data) for link_ in object_.get_links('P25', inverse=True): data = get_base_table_data(link_.domain) if is_authorized('contributor'): url = url_for('link_delete', id_=link_.id, origin_id=object_.id) data.append( display_remove_link(url + '#tab-' + link_.range.table_name, link_.range.name)) tables['event'].rows.append(data) return render_template('object/view.html', object_=object_, tables=tables)
def get_table(view: str) -> Table: table = Table(g.table_headers[view]) if view == 'file': table.header = ['date'] + table.header file_stats = get_file_stats() for entity in Entity.get_by_class('file', nodes=True): date = 'N/A' if entity.id in file_stats: date = format_date( datetime.datetime.utcfromtimestamp( file_stats[entity.id]['date'])) table.rows.append([ date, link(entity), entity.print_standard_type(), convert_size(file_stats[entity.id]['size']) if entity.id in file_stats else 'N/A', file_stats[entity.id]['ext'] if entity.id in file_stats else 'N/A', entity.description ]) elif view == 'reference_system': for system in g.reference_systems.values(): table.rows.append([ link(system), system.count if system.count else '', external_url(system.website_url), external_url(system.resolver_url), system.placeholder, link(g.nodes[system.precision_default_id]) if system.precision_default_id else '', system.description ]) else: classes = ['place'] if view == 'place' else g.view_class_mapping[view] entities = Entity.get_by_class(classes, nodes=True) table.rows = [get_base_table_data(item) for item in entities] return table
def build_table_form(class_: str, linked_entities: List[Entity]) -> str: """ Returns a form with a list of entities with checkboxes.""" if class_ == 'file': entities = Entity.get_by_class('file', nodes=True) elif class_ == 'place': entities = Entity.get_by_class('place', nodes=True, aliases=True) else: entities = Entity.get_by_view(class_) linked_ids = [entity.id for entity in linked_entities] table = Table([''] + g.table_headers[class_], order=[[1, 'asc']]) file_stats = get_file_stats() if class_ == 'file' else None for entity in entities: if entity.id in linked_ids: continue # Don't show already linked entries input_ = '<input id="selection-{id}" name="values" type="checkbox" value="{id}">'.format( id=entity.id) table.rows.append([input_] + get_base_table_data(entity, file_stats)) if not table.rows: return uc_first(_('no entries')) return """ <form class="table" id="checkbox-form" method="post"> <input id="csrf_token" name="csrf_token" type="hidden" value="{token}"> <input id="checkbox_values" name="checkbox_values" type="hidden"> {table} <input id="save" class="{class_}" name="save" type="submit" value="{link}"> </form>""".format(link=uc_first(_('link')), token=generate_csrf(), class_=app.config['CSS']['button']['primary'], table=table.display(class_))
def index() -> str: tables = {'overview': Table(paging=False, defs='[{className: "dt-body-right", targets: 1}]'), 'bookmarks': Table(['name', 'class', 'first', 'last'], defs='[{className: "dt-body-right", targets: [2,3]}]'), 'notes': Table(['name', 'class', 'first', 'last', _('note')], defs='[{className: "dt-body-right", targets: [2,3]}]'), 'latest': Table(['name', 'class', 'first', 'last', 'date', 'user'], order='[[4, "desc"]]', defs='[{className: "dt-body-right", targets: [2,3]}]')} if current_user.is_authenticated and hasattr(current_user, 'bookmarks'): for entity_id in current_user.bookmarks: entity = EntityMapper.get_by_id(entity_id) tables['bookmarks'].rows.append([link(entity), g.classes[entity.class_.code].name, entity.first, entity.last, bookmark_toggle(entity.id, True)]) for entity_id, text in UserMapper.get_notes().items(): entity = EntityMapper.get_by_id(entity_id) tables['notes'].rows.append([link(entity), g.classes[entity.class_.code].name, entity.first, entity.last, truncate_string(text)]) for name, count in EntityMapper.get_overview_counts().items(): if count: count = format_number(count) if count else '' url = url_for(name + '_index') if name != 'find' else url_for('place_index') tables['overview'].rows.append([ '<a href="' + url + '">' + uc_first(_(name)) + '</a>', count]) for entity in EntityMapper.get_latest(8): tables['latest'].rows.append([ link(entity), g.classes[entity.class_.code].name, entity.first, entity.last, format_date(entity.created), link(logger.get_log_for_advanced_view(entity.id)['creator'])]) intro = ContentMapper.get_translation('intro') return render_template('index/index.html', intro=intro, tables=tables)
def build_table_form(class_name: str, linked_entities: Iterator) -> str: """ Returns a form with a list of entities with checkboxes""" from openatlas.models.entity import EntityMapper table = Table(Table.HEADERS[class_name] + ['']) linked_ids = [entity.id for entity in linked_entities] file_stats = get_file_stats() if class_name == 'file' else None if class_name == 'file': entities = EntityMapper.get_by_system_type('file', nodes=True) elif class_name == 'place': entities = EntityMapper.get_by_system_type('place', nodes=True, aliases=True) else: entities = EntityMapper.get_by_codes(class_name) for entity in entities: if entity.id in linked_ids: continue # Don't show already linked entries input_ = '<input id="selection-{id}" name="values" type="checkbox" value="{id}">'.format( id=entity.id) table.rows.append(get_base_table_data(entity, file_stats) + [input_]) if not table.rows: return uc_first(_('no entries')) return """ <form class="table" id="checkbox-form" method="post"> <input id="csrf_token" name="csrf_token" type="hidden" value="{token}"> <input id="checkbox_values" name="checkbox_values" type="hidden"> {table} <button name="form-submit" id="form-submit" type="submit">{add}</button> </form>""".format(add=uc_first(_('add')), token=generate_csrf(), table=table.display(class_name))
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 admin_check_dates() -> str: tabs = { 'dates': Tab('invalid_dates', table=Table( ['name', 'class', 'type', 'created', 'updated', 'description'])), 'link_dates': Tab('invalid_link_dates', table=Table(['link', 'domain', 'range'])), 'involvement_dates': Tab('invalid_involvement_dates', table=Table( ['actor', 'event', 'class', 'involvement', 'description'])) } for entity in Entity.get_invalid_dates(): tabs['dates'].table.rows.append([ link(entity), entity.class_.label, link(entity.standard_type), format_date(entity.created), format_date(entity.modified), entity.description ]) for link_ in Link.get_invalid_link_dates(): name = '' if link_.property.code == 'OA7': # pragma: no cover name = 'relation' elif link_.property.code == 'P107': # pragma: no cover name = 'member' elif link_.property.code in ['P11', 'P14', 'P22', 'P23']: name = 'involvement' tabs['link_dates'].table.rows.append([ link( _(name), url_for('link_update', id_=link_.id, origin_id=link_.domain.id)), link(link_.domain), link(link_.range) ]) for link_ in Link.invalid_involvement_dates(): event = link_.domain actor = link_.range data = [ link(actor), link(event), event.class_.label, link_.type.name if link_.type else '', link_.description, link(_('edit'), url_for('link_update', id_=link_.id, origin_id=actor.id)) ] tabs['involvement_dates'].table.rows.append(data) for tab in tabs.values(): tab.buttons = [manual('admin/data_integrity_checks')] if not tab.table.rows: # pragma: no cover tab.content = _('Congratulations, everything looks fine!') return render_template( 'tabs.html', tabs=tabs, title=_('admin'), crumbs=[[_('admin'), f"{url_for('admin_index')}#tab-data"], _('check dates')])
def table_select_model(self: Any, name: str, selected: Union[CidocClass, CidocProperty, None] = None) -> str: if name in ['domain', 'range']: entities = g.cidoc_classes else: entities = g.properties table = Table(['code', 'name'], defs=[ {'orderDataType': 'cidoc-model', 'targets': [0]}, {'sType': 'numeric', 'targets': [0]}]) for id_ in entities: table.rows.append([ """<a onclick="selectFromTable(this, '{name}', '{entity_id}', '{value}')" href="#">{label}</a>""".format( name=name, entity_id=id_, value=entities[id_].code + ' ' + entities[id_].name, label=entities[id_].code), """<a onclick="selectFromTable(this, '{name}', '{entity_id}', '{value}')" href="#">{label}</a>""".format( name=name, entity_id=id_, value=entities[id_].code + ' ' + entities[id_].name, label=entities[id_].name)]) value = selected.code + ' ' + selected.name if selected else '' html = """ <input id="{name}-button" name="{name}-button" class="table-select" type="text" onfocus="this.blur()" readonly="readonly" value="{value}" onclick="$('#{name}-modal').modal('show')"> <div id="{name}-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal-dialog" role="document" style="max-width: 100%!important;"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">{name}</h5> <button type="button" class="btn btn-outline-primary btn-sm" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body">{table}</div> <div class="modal-footer"> <button type="button" class="btn btn-outline-primary btn-sm" data-dismiss="modal">{close_label}</button> </div> </div> </div> </div>""".format( name=name, value=value, close_label=display.uc_first(_('close')), table=table.display(name)) return html
def __call__(self, field: TableField, **kwargs: Any) -> TableSelect: selection = '' if field.id in ('cidoc_domain', 'cidoc_property', 'cidoc_range'): table = Table(['code', 'name'], order=[[0, 'desc']], defs=[{ 'orderDataType': 'cidoc-model', 'targets': [0] }, { 'sType': 'numeric', 'targets': [0] }]) for id_, entity in (g.properties if field.id == 'cidoc_property' else g.cidoc_classes).items(): table.rows.append([ f""" <a href="#" onclick="selectFromTable( this, '{field.id}', '{id_}', '{entity.code} {entity.name}');">{entity.code}</a>""", entity.name ]) else: aliases = current_user.settings['table_show_aliases'] if 'place' in field.id \ or field.id in ['begins_in', 'ends_in', 'residence']: class_ = 'place' entities = Entity.get_by_class('place', types=True, aliases=aliases) elif field.id.startswith('event_'): class_ = 'event' entities = Entity.get_by_view('event', types=True, aliases=aliases) else: class_ = field.id entities = Entity.get_by_view(class_, types=True, aliases=aliases) table = Table(g.table_headers[class_]) for entity in entities: if field.data and entity.id == int(field.data): selection = entity.name data = get_base_table_data(entity, show_links=False) data[0] = self.format_name_and_aliases(entity, field.id) table.rows.append(data) return super().__call__(field, **kwargs) + render_template( 'forms/table_select.html', field=field, table=table.display(field.id), selection=selection)
def admin_check_dates() -> str: # Get invalid date combinations (e.g. begin after end) tables = { 'link_dates': Table(['link', 'domain', 'range']), 'involvement_dates': Table(['actor', 'event', 'class', 'involvement', 'description']), 'dates': Table(['name', 'class', 'type', 'created', 'updated', 'description']) } for entity in Date.get_invalid_dates(): tables['dates'].rows.append([ link(entity), entity.class_.label, entity.print_standard_type(), format_date(entity.created), format_date(entity.modified), entity.description ]) for link_ in Date.get_invalid_link_dates(): label = '' if link_.property.code == 'OA7': # pragma: no cover label = 'relation' elif link_.property.code == 'P107': # pragma: no cover label = 'member' elif link_.property.code in ['P11', 'P14', 'P22', 'P23']: label = 'involvement' tables['link_dates'].rows.append([ link( _(label), url_for(label + '_update', id_=link_.id, origin_id=link_.domain.id)), link(link_.domain), link(link_.range) ]) for link_ in Date.invalid_involvement_dates(): event = link_.domain actor = link_.range data = [ link(actor), link(event), event.class_.label, link_.type.name if link_.type else '', link_.description, link( _('edit'), url_for('involvement_update', id_=link_.id, origin_id=actor.id)) ] tables['involvement_dates'].rows.append(data) return render_template( 'admin/check_dates.html', tables=tables, title=_('admin'), crumbs=[[_('admin'), url_for('admin_index') + '#tab-data'], _('check dates')])
def __call__(self, field, **kwargs): if field.data and type(field.data) is str: field.data = ast.literal_eval(field.data) selection = '' class_ = field.id if field.id != 'given_place' else 'place' headers_len = str(len(Table.HEADERS[class_])) # Make checkbox column sortable and show selected on top table = Table(Table.HEADERS[class_], order='[[' + headers_len + ', "desc"], [0, "asc"]]') # Table definitions (ordering and aligning) defs = '{"orderDataType": "dom-checkbox", "targets":' + headers_len + '}' if class_ == 'event': defs += ',{className: "dt-body-right", targets: [3,4]}' elif class_ in ['actor', 'group', 'feature', 'place']: defs += ',{className: "dt-body-right", targets: [2,3]}' table.defs = '[' + defs + ']' if class_ == 'place': aliases = current_user.settings['table_show_aliases'] entities = EntityMapper.get_by_system_type('place', nodes=True, aliases=aliases) else: entities = EntityMapper.get_by_codes(class_) for entity in entities: selection += entity.name + '<br/>' if field.data and entity.id in field.data else '' data = get_base_table_data(entity) data[0] = re.sub(re.compile('<a.*?>'), '', data[0]) # Remove links data.append( """<input type="checkbox" id="{id}" {checked} value="{name}" class="multi-table-select">""".format( id=str(entity.id), name=entity.name, checked='checked = "checked"' if field.data and entity.id in field.data else '')) table.rows.append(data) html = """ <span id="{name}-button" class="button">{change_label}</span><br /> <div id="{name}-selection" class="selection" style="text-align:left;">{selection}</div> <div id="{name}-overlay" class="overlay"> <div id="{name}-dialog" class="overlay-container">{table}</div></div> <script> $(document).ready(function () {{createOverlay("{name}", "{title}", true);}}); </script>""".format(name=field.id, change_label=uc_first(_('change')), title=_(field.id.replace('_', ' ')), selection=selection, table=table.display(field.id)) return super(TableMultiSelect, self).__call__(field, **kwargs) + html
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 reference_view(id_: int) -> str: reference = EntityMapper.get_by_id(id_, nodes=True) reference.note = UserMapper.get_note(reference) tables = { 'info': get_entity_data(reference), 'file': Table(Table.HEADERS['file'] + ['page', _('main image')]) } for name in [ 'source', 'event', 'actor', 'place', 'feature', 'stratigraphic-unit', 'find' ]: header_label = 'link text' if reference.system_type == 'external reference' else 'page' tables[name] = Table(Table.HEADERS[name] + [header_label]) for link_ in reference.get_links('P67', True): domain = link_.domain data = get_base_table_data(domain) if is_authorized('contributor'): url = url_for('link_delete', id_=link_.id, origin_id=reference.id) + '#tab-file' data.append(display_remove_link(url, domain.name)) tables['file'].rows.append(data) profile_image_id = reference.get_profile_image_id() for link_ in reference.get_links(['P67', 'P128']): range_ = link_.range data = get_base_table_data(range_) data.append(truncate_string(link_.description)) if range_.view_name == 'file': # pragma: no cover ext = data[3].replace('.', '') data.append( get_profile_image_table_link(range_, reference, ext, profile_image_id)) if not profile_image_id and ext in app.config[ 'DISPLAY_FILE_EXTENSIONS']: profile_image_id = range_.id if is_authorized('contributor'): url = url_for('reference_link_update', link_id=link_.id, origin_id=reference.id) data.append('<a href="' + url + '">' + uc_first(_('edit')) + '</a>') url = url_for('link_delete', id_=link_.id, origin_id=reference.id) data.append( display_remove_link(url + '#tab-' + range_.table_name, range_.name)) tables[range_.table_name].rows.append(data) return render_template('reference/view.html', reference=reference, tables=tables, profile_image_id=profile_image_id)
def display_move_form(self, form, root_name: str) -> str: html = '' for field in form: if type(field) is TreeField: html += '<p>' + root_name + ' ' + str(field) + '</p>' html += """ <p> <a class="button" id="select-all">{select_all}</a> <a class="button" id="select-none">{deselect_all}</a> </p>""".format(select_all=util.uc_first(_('select all')), deselect_all=util.uc_first(_('deselect all'))) table = Table(['#', util.uc_first(_('selection'))]) for item in form.selection: table.rows.append([item, item.label.text]) return html + table.display('move')
def class_view(code: str) -> str: class_ = g.cidoc_classes[code] tables = {} for table in ['super', 'sub']: tables[table] = Table(paging=False, defs=[{ 'orderDataType': 'cidoc-model', 'targets': [0] }, { 'sType': 'numeric', 'targets': [0] }]) for code_ in getattr(class_, table): tables[table].rows.append( [link(g.cidoc_classes[code_]), g.cidoc_classes[code_].name]) tables['domains'] = Table(paging=False, defs=[{ 'orderDataType': 'cidoc-model', 'targets': [0] }, { 'sType': 'numeric', 'targets': [0] }]) tables['ranges'] = Table(paging=False, defs=[{ 'orderDataType': 'cidoc-model', 'targets': [0] }, { 'sType': 'numeric', 'targets': [0] }]) for key, property_ in g.properties.items(): if class_.code == property_.domain_class_code: tables['domains'].rows.append([link(property_), property_.name]) elif class_.code == property_.range_class_code: tables['ranges'].rows.append([link(property_), property_.name]) return render_template('model/class_view.html', class_=class_, tables=tables, info={ 'code': class_.code, 'name': class_.name }, title=_('model'), crumbs=[[_('model'), url_for('model_index')], [_('classes'), url_for('class_index')], class_.code])
def admin_logo(id_: Optional[int] = None) -> Union[str, Response]: if g.settings['logo_file_id']: abort(418) # pragma: no cover - Logo already set if id_: Settings.set_logo(id_) return redirect(f"{url_for('admin_index')}#tab-file") table = Table([''] + g.table_headers['file'] + ['date']) for entity in Entity.get_display_files(): date = 'N/A' if entity.id in g.file_stats: date = format_date( datetime.datetime.utcfromtimestamp( g.file_stats[entity.id]['date'])) table.rows.append([ link(_('set'), url_for('admin_logo', id_=entity.id)), entity.name, link(entity.standard_type), g.file_stats[entity.id]['size'] if entity.id in g.file_stats else 'N/A', g.file_stats[entity.id]['ext'] if entity.id in g.file_stats else 'N/A', entity.description, date ]) return render_template( 'admin/logo.html', table=table, title=_('logo'), crumbs=[[_('admin'), f"{url_for('admin_index')}#tab-files"], _('logo')])
def node_move_entities(id_: int) -> Union[str, Response]: node = g.nodes[id_] root = g.nodes[node.root[-1]] if root.value_type: # pragma: no cover abort(403) form = build_move_form(node) if form.validate_on_submit(): Transaction.begin() Node.move_entities(node, getattr(form, str(root.id)).data, form.checkbox_values.data) Transaction.commit() flash(_('Entities were updated'), 'success') if node.class_.name == 'administrative_unit': tab = 'places' elif root.standard: tab = 'standard' elif node.value_type: # pragma: no cover tab = 'value' else: tab = 'custom' return redirect( f"{url_for('node_index')}#menu-tab-{tab}_collapse-{root.id}") getattr(form, str(root.id)).data = node.id return render_template('types/move.html', table=Table(header=['#', _('selection')], rows=[[item, item.label.text] for item in form.selection]), root=root, form=form, entity=node, crumbs=[[_('types'), url_for('node_index')], root, node, _('move entities')])
def object_index() -> str: table = Table(Table.HEADERS['object'] + ['description']) for object_ in EntityMapper.get_by_codes('object'): data = get_base_table_data(object_) data.append(truncate_string(object_.description)) table.rows.append(data) return render_template('object/index.html', table=table)
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 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 admin_log() -> str: form = LogForm() form.user.choices = [(0, _('all'))] + User.get_users_for_form() table = Table(['date', 'priority', 'type', 'message', 'user', 'info'], order=[[0, 'desc']]) logs = logger.get_system_logs(form.limit.data, form.priority.data, form.user.data) for row in logs: user = None if row['user_id']: try: user = link(User.get_by_id(row['user_id'])) except AttributeError: # pragma: no cover - user already deleted user = f"id {row['user_id']}" table.rows.append([ format_datetime(row['created']), f"{row['priority']} {app.config['LOG_LEVELS'][row['priority']]}", row['type'], row['message'], user, row['info'] ]) return render_template( 'admin/log.html', table=table, form=form, title=_('admin'), crumbs=[[_('admin'), f"{url_for('admin_index')}#tab-general"], _('system log')])
def file_index() -> str: table = Table(['date'] + Table.HEADERS['file']) file_stats = get_file_stats() for entity in EntityMapper.get_by_system_type('file', nodes=True): date = 'N/A' if entity.id in file_stats: date = format_date( datetime.datetime.utcfromtimestamp( file_stats[entity.id]['date'])) table.rows.append([ date, link(entity), entity.print_base_type(), convert_size(file_stats[entity.id]['size']) if entity.id in file_stats else 'N/A', file_stats[entity.id]['ext'] if entity.id in file_stats else 'N/A', truncate_string(entity.description) ]) if os.name != "posix": # pragma: no cover # For other operating systems e.g. Windows, we would need adaptions here return render_template('file/index.html', table=table, disk_space_values={}) statvfs = os.statvfs(app.config['UPLOAD_FOLDER_PATH']) disk_space = statvfs.f_frsize * statvfs.f_blocks free_space = statvfs.f_frsize * statvfs.f_bavail # Available space without reserved blocks disk_space_values = { 'total': convert_size(statvfs.f_frsize * statvfs.f_blocks), 'free': convert_size(statvfs.f_frsize * statvfs.f_bavail), 'percent': 100 - math.ceil(free_space / (disk_space / 100)) } return render_template('file/index.html', table=table, disk_space_values=disk_space_values)
def type_move_entities(id_: int) -> Union[str, Response]: type_ = g.types[id_] root = g.types[type_.root[0]] if root.category == 'value': abort(403) # pragma: no cover form = build_move_form(type_) if form.validate_on_submit(): Transaction.begin() Type.move_entities(type_, getattr(form, str(root.id)).data, form.checkbox_values.data) Transaction.commit() flash(_('Entities were updated'), 'success') return redirect(f"{url_for('type_index')}" f"#menu-tab-{type_.category}_collapse-{root.id}") getattr(form, str(root.id)).data = type_.id return render_template('type/move.html', table=Table(header=['#', _('selection')], rows=[[item, item.label.text] for item in form.selection]), root=root, form=form, entity=type_, crumbs=[[_('types'), url_for('type_index')], root, type_, _('move entities')])
def openatlas_class_index() -> str: table = Table([ 'name', f"CIDOC {_('class')}", _('standard type'), _('write access'), 'alias', _('reference system'), 'add type', _('color'), _('icon'), 'count' ]) class_count = OpenatlasClass.get_class_count() for class_ in g.classes.values(): table.rows.append([ class_.label, link(class_.cidoc_class), link(g.types[class_.standard_type_id]) if class_.standard_type_id else '', class_.write_access, _('allowed') if class_.alias_allowed else '', _('allowed') if class_.reference_system_allowed else '', _('allowed') if class_.new_types_allowed else '', class_.network_color, class_.icon, format_number(class_count[class_.name]) if class_count[class_.name] else '' ]) return render_template('table.html', table=table, title=_('model'), crumbs=[[_('model'), url_for('model_index')], f"OpenAtlas {_('classes')}"])
def __init__(self, name: str, content: Optional[str] = None, table: Optional[Table] = None, buttons: Optional[List[str]] = None, entity: Optional['Entity'] = None) -> None: self.name = name self.content = content self.title = uc_first(_(name.replace('_', ' '))) self.entity = entity self.table = table if table else Table() id_ = None view = None class_ = None if entity: id_ = entity.id view = entity.class_.view class_ = entity.class_ self.table.header = g.table_headers[name] if name == 'reference' or entity and entity.class_.view == 'reference': self.table.header = self.table.header + ['page'] buttons = buttons if buttons else [] self.add_buttons(name, buttons, view, id_, class_) self.buttons = buttons \ if buttons and is_authorized('contributor') else []
def property_view(code: str) -> str: property_ = g.properties[code] domain = g.cidoc_classes[property_.domain_class_code] range_ = g.cidoc_classes[property_.range_class_code] info = { 'code': property_.code, 'name': property_.name, 'inverse': property_.name_inverse, 'domain': f'{link(domain)} {domain.name}', 'range': f'{link(range_)} {range_.name}' } tables = {} for table in ['super', 'sub']: tables[table] = Table(paging=False, defs=[{ 'orderDataType': 'cidoc-model', 'targets': [0] }, { 'sType': 'numeric', 'targets': [0] }]) for code_ in getattr(property_, table): tables[table].rows.append( [link(g.properties[code_]), g.properties[code_].name]) return render_template( 'model/property_view.html', tables=tables, property_=property_, info=info, title=_('model'), crumbs=[[_('model'), url_for('model_index')], [_('properties'), url_for('property_index')], property_.code])
def property_index() -> str: classes = g.cidoc_classes properties = g.properties table = Table([ 'code', 'name', 'inverse', 'domain', 'domain name', 'range', 'range name', 'count' ], defs=[{ 'className': 'dt-body-right', 'targets': 7 }, { 'orderDataType': 'cidoc-model', 'targets': [0, 3, 5] }, { 'sType': 'numeric', 'targets': [0] }]) for property_ in properties.values(): table.rows.append([ link(property_), property_.name, property_.name_inverse, link(classes[property_.domain_class_code]), classes[property_.domain_class_code].name, link(classes[property_.range_class_code]), classes[property_.range_class_code].name, format_number(property_.count) if property_.count else '' ]) return render_template('table.html', table=table, title=_('model'), crumbs=[[_('model'), url_for('model_index')], _('properties')])
def cidoc_class_index() -> str: table = Table(['code', 'name', 'count'], defs=[{ 'className': 'dt-body-right', 'targets': 2 }, { 'orderDataType': 'cidoc-model', 'targets': [0] }, { 'sType': 'numeric', 'targets': [0] }]) for class_ in g.cidoc_classes.values(): count = '' if class_.count: count = format_number(class_.count) if class_.code not in ['E53', 'E41', 'E82']: count = link(format_number(class_.count), url_for('class_entities', code=class_.code)) table.rows.append([link(class_), class_.name, count]) return render_template('table.html', table=table, title=_('model'), crumbs=[[_('model'), url_for('model_index')], _('classes')])
def __call__(self, field, **kwargs): file_stats = None class_ = 'place' if field.id in ['residence', 'begins_in', 'ends_in'] else field.id if class_ == 'place': aliases = current_user.settings['table_show_aliases'] entities = EntityMapper.get_by_system_type('place', nodes=True, aliases=aliases) elif class_ == 'reference': entities = EntityMapper.get_by_system_type('bibliography') + \ EntityMapper.get_by_system_type('edition') + \ EntityMapper.get_by_system_type('external reference') elif class_ == 'file': entities = EntityMapper.get_display_files() file_stats = get_file_stats() else: entities = EntityMapper.get_by_codes(class_) selection = '' table = Table(Table.HEADERS[class_]) for entity in entities: # Todo: don't show self e.g. at source if field.data and entity.id == int(field.data): selection = entity.name data = get_base_table_data(entity, file_stats) data[0] = """<a onclick="selectFromTable(this,'{name}', {entity_id})">{entity_name}</a> """.format(name=field.id, entity_id=entity.id, entity_name=truncate_string(entity.name, span=False)) data[0] = '<br />'.join([data[0]] + [ truncate_string(alias) for id_, alias in entity.aliases.items()]) table.rows.append(data) html = """ <input id="{name}-button" name="{name}-button" class="table-select {required}" type="text" placeholder="{change_label}" onfocus="this.blur()" readonly="readonly" value="{selection}"> <a id="{name}-clear" class="button" {clear_style} onclick="clearSelect('{name}');">{clear_label}</a> <div id="{name}-overlay" class="overlay"> <div id="{name}-dialog" class="overlay-container">{table}</div></div> <script>$(document).ready(function () {{createOverlay("{name}", "{title}");}});</script> """.format(name=field.id, title=_(field.id.replace('_', ' ')), change_label=uc_first(_('change')), clear_label=uc_first(_('clear')), table=table.display(field.id), selection=selection, clear_style='' if selection else ' style="display: none;" ', required=' required' if field.flags.required else '') return super(TableSelect, self).__call__(field, **kwargs) + html
def __call__(self, field, **kwargs): if field.data and type(field.data) is str: field.data = ast.literal_eval(field.data) selection = '' class_ = field.id if field.id != 'given_place' else 'place' table = Table(Table.HEADERS[class_]) # Make checkbox column sortable and show selected on top table.headers = 'headers:{' + str(len(table.header)) + ':{sorter:"checkbox"}},' table.sort = 'sortList:[[' + str(len(table.header)) + ', 0],[0, 0]],' if class_ == 'place': aliases = current_user.settings['table_show_aliases'] entities = EntityMapper.get_by_system_type('place', nodes=True, aliases=aliases) else: entities = EntityMapper.get_by_codes(class_) for entity in entities: selection += entity.name + '<br/>' if field.data and entity.id in field.data else '' data = get_base_table_data(entity) data[0] = re.sub(re.compile('<a.*?>'), '', data[0]) # Remove links data.append("""<input type="checkbox" id="{id}" {checked} value="{name}" class="multi-table-select">""".format( id=str(entity.id), name=entity.name, checked='checked = "checked"' if field.data and entity.id in field.data else '')) table.rows.append(data) html = """ <span id="{name}-button" class="button">{change_label}</span><br /> <div id="{name}-selection" class="selection" style="text-align:left;">{selection}</div> <div id="{name}-overlay" class="overlay"> <div id="{name}-dialog" class="overlay-container">{table}</div></div> <script> $(document).ready(function () {{createOverlay("{name}", "{title}", true);}}); </script>""".format(name=field.id, change_label=uc_first(_('change')), title=_(field.id.replace('_', ' ')), selection=selection, table=table.display(field.id, remove_rows=False)) return super(TableMultiSelect, self).__call__(field, **kwargs) + html