Example #1
0
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 reference_view(id_):
    reference = EntityMapper.get_by_id(id_)
    tables = {
        'info': get_entity_data(reference),
        'file': {'id': 'files', 'data': [],
                 'header': app.config['TABLE_HEADERS']['file'] + ['page'] + [_('main image')]}}
    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):
        domain = link_.domain
        data = get_base_table_data(domain)
        if is_authorized('editor'):
            url = url_for('link_delete', id_=link_.id, origin_id=reference.id) + '#tab-file'
            data.append(display_remove_link(url, domain.name))
        tables['file']['data'].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('editor'):
            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]['data'].append(data)
    return render_template('reference/view.html', reference=reference, tables=tables,
                           profile_image_id=profile_image_id)
def event_view(id_):
    event = EntityMapper.get_by_id(id_)
    event.set_dates()
    tables = {
        'info': get_entity_data(event),
        'file': {'id': 'files', 'data': [],
                 'header': app.config['TABLE_HEADERS']['file'] + [_('main image')]},
        'subs': {'id': 'sub-event', 'data': [], 'header': app.config['TABLE_HEADERS']['event']},
        'source': {'id': 'source', 'data': [], 'header': app.config['TABLE_HEADERS']['source']},
        'actor': {'id': 'actor', 'data': [],
                  'header': ['actor', 'class', 'involvement', 'first', 'last', 'description']},
        'reference': {'id': 'reference', 'data': [],
                      'header': app.config['TABLE_HEADERS']['reference'] + ['pages']}}
    for link_ in event.get_links(['P11', 'P14', 'P22', 'P23']):
        first = link_.first
        if not link_.first and event.first:
            first = '<span class="inactive" style="float:right">' + str(event.first) + '</span>'
        last = link_.last
        if not link_.last and event.last:
            last = '<span class="inactive" style="float:right">' + str(event.last) + '</span>'
        data = ([link(link_.range),
                 g.classes[link_.range.class_.code].name,
                 link_.type.name if link_.type else '',
                 first, last,
                 truncate_string(link_.description)])
        if is_authorized('editor'):
            update_url = url_for('involvement_update', id_=link_.id, origin_id=event.id)
            unlink_url = url_for('link_delete', id_=link_.id, origin_id=event.id) + '#tab-actor'
            data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>')
            data.append(display_remove_link(unlink_url, link_.range.name))
        tables['actor']['data'].append(data)
    profile_image_id = event.get_profile_image_id()
    for link_ in event.get_links('P67', True):
        domain = link_.domain
        data = get_base_table_data(domain)
        if domain.view_name == 'file':  # pragma: no cover
            extension = data[3].replace('.', '')
            data.append(get_profile_image_table_link(domain, event, extension, profile_image_id))
            if not profile_image_id and extension in app.config['DISPLAY_FILE_EXTENSIONS']:
                profile_image_id = domain.id
        if domain.view_name not in ['source', 'file']:
            data.append(truncate_string(link_.description))
            if is_authorized('editor'):
                update_url = url_for('reference_link_update', link_id=link_.id, origin_id=event.id)
                data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>')
        if is_authorized('editor'):
            url = url_for('link_delete', id_=link_.id, origin_id=event.id)
            data.append(display_remove_link(url + '#tab-' + domain.view_name, domain.name))
        tables[domain.view_name]['data'].append(data)
    for sub_event in event.get_linked_entities('P117', True):
        tables['subs']['data'].append(get_base_table_data(sub_event))
    return render_template('event/view.html', event=event, tables=tables,
                           profile_image_id=profile_image_id)
Example #4
0
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
Example #5
0
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)
Example #6
0
def reference_index() -> str:
    table = Table(Table.HEADERS['reference'] + ['description'])
    for reference in EntityMapper.get_by_codes('reference'):
        data = get_base_table_data(reference)
        data.append(truncate_string(reference.description))
        table.rows.append(data)
    return render_template('reference/index.html', table=table)
Example #7
0
def add_tabs_for_event(entity: Entity) -> dict[str, Tab]:
    tabs = {}
    for name in ['subs', 'source', 'actor']:
        tabs[name] = Tab(name, entity=entity)
    for sub_event in entity.get_linked_entities(
            'P9',
            inverse=True,
            types=True):
        tabs['subs'].table.rows.append(get_base_table_data(sub_event))
    tabs['actor'].table.header.insert(5, _('activity'))
    for link_ in entity.get_links(['P11', 'P14', 'P22', 'P23']):
        first = link_.first
        if not link_.first and entity.first:
            first = f'<span class="inactive">{entity.first}</span>'
        last = link_.last
        if not link_.last and entity.last:
            last = f'<span class="inactive">{entity.last}</span>'
        tabs['actor'].table.rows.append([
            link(link_.range),
            link_.range.class_.label,
            link_.type.name if link_.type else '',
            first,
            last,
            g.properties[link_.property.code].name_inverse,
            link_.description,
            edit_link(
                url_for('link_update', id_=link_.id, origin_id=entity.id)),
            remove_link(link_.range.name, link_, entity, 'actor')])
    entity.linked_places = [
        location.get_linked_entity_safe('P53', True) for location
        in entity.get_linked_entities(['P7', 'P26', 'P27'])]
    return tabs
Example #8
0
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))
Example #9
0
 def __call__(self, field: TableField, **kwargs: Any) -> TableMultiSelect:
     if field.data and isinstance(field.data, str):
         field.data = ast.literal_eval(field.data)
     class_ = field.id if field.id != 'given_place' else 'place'
     aliases = current_user.settings['table_show_aliases']
     if class_ in ['group', 'person', 'place']:
         entities = Entity.get_by_class(class_, types=True, aliases=aliases)
     else:
         entities = Entity.get_by_view(class_, types=True, aliases=aliases)
     table = Table([''] + g.table_headers[class_],
                   order=[[0, 'desc'], [1, 'asc']],
                   defs=[{
                       'orderDataType': 'dom-checkbox',
                       'targets': 0
                   }])
     for e in entities:
         data = get_base_table_data(e, show_links=False)
         data.insert(
             0, f"""
             <input type="checkbox" id="{e.id}" value="{e.name}"
             {'checked' if field.data and e.id in field.data else ''}>""")
         table.rows.append(data)
     return super().__call__(field, **kwargs) + render_template(
         'forms/table_multi_select.html',
         field=field,
         selection=[
             e.name for e in entities if field.data and e.id in field.data
         ],
         table=table)
Example #10
0
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)
Example #11
0
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)
Example #12
0
def actor_index():
    header = app.config['TABLE_HEADERS']['actor'] + ['description']
    table = {'id': 'actor', 'header': header, 'data': []}
    for actor in EntityMapper.get_by_codes('actor'):
        data = get_base_table_data(actor)
        data.append(truncate_string(actor.description))
        table['data'].append(data)
    return render_template('actor/index.html', table=table)
Example #13
0
def reference_index():
    header = app.config['TABLE_HEADERS']['reference'] + ['description']
    table = {'id': 'reference', 'header': header, 'data': []}
    for reference in EntityMapper.get_by_codes('reference'):
        data = get_base_table_data(reference)
        data.append(truncate_string(reference.description))
        table['data'].append(data)
    return render_template('reference/index.html', table=table)
def reference_index():
    header = app.config['TABLE_HEADERS']['reference'] + ['description']
    table = {'id': 'reference', 'header': header, 'data': []}
    for reference in EntityMapper.get_by_codes('reference'):
        data = get_base_table_data(reference)
        data.append(truncate_string(reference.description))
        table['data'].append(data)
    return render_template('reference/index.html', table=table)
def event_index():
    header = app.config['TABLE_HEADERS']['event'] + ['description']
    table = {'id': 'event', 'header': header, 'data': []}
    for event in EntityMapper.get_by_codes('event'):
        data = get_base_table_data(event)
        data.append(truncate_string(event.description))
        table['data'].append(data)
    return render_template('event/index.html', table=table)
Example #16
0
def actor_index() -> str:
    table = Table(Table.HEADERS['actor'] + ['description'],
                  defs='[{className: "dt-body-right", targets: [2,3]}]')
    for actor in EntityMapper.get_by_codes('actor'):
        data = get_base_table_data(actor)
        data.append(truncate_string(actor.description))
        table.rows.append(data)
    return render_template('actor/index.html', table=table)
Example #17
0
def event_index():
    header = app.config['TABLE_HEADERS']['event'] + ['description']
    table = {'id': 'event', 'header': header, 'data': []}
    for event in EntityMapper.get_by_codes('event'):
        data = get_base_table_data(event)
        data.append(truncate_string(event.description))
        table['data'].append(data)
    return render_template('event/index.html', table=table)
def actor_index():
    header = app.config['TABLE_HEADERS']['actor'] + ['description']
    table = {'id': 'actor', 'header': header, 'data': []}
    for actor in EntityMapper.get_by_codes('actor'):
        data = get_base_table_data(actor)
        data.append(truncate_string(actor.description))
        table['data'].append(data)
    return render_template('actor/index.html', table=table)
Example #19
0
def event_index() -> str:
    table = Table(Table.HEADERS['event'] + ['description'],
                  defs='[{className: "dt-body-right", targets: [3,4]}]')
    for event in EntityMapper.get_by_codes('event'):
        data = get_base_table_data(event)
        data.append(truncate_string(event.description))
        table.rows.append(data)
    return render_template('event/index.html', table=table)
Example #20
0
def file_view(id_: int) -> str:
    file = EntityMapper.get_by_id(id_, nodes=True)
    path = get_file_path(file.id)
    tables = {'info': get_entity_data(file)}
    for name in [
            'source', 'event', 'actor', 'place', 'feature',
            'stratigraphic-unit', 'find', 'reference'
    ]:
        tables[name] = Table(Table.HEADERS[name] +
                             (['page'] if name == 'reference' else []))
    for link_ in file.get_links('P67'):
        range_ = link_.range
        data = get_base_table_data(range_)
        view_name = range_.view_name
        view_name = view_name if view_name != 'place' else range_.system_type.replace(
            ' ', '-')
        if is_authorized('contributor'):
            url = url_for('link_delete', id_=link_.id, origin_id=file.id)
            data.append(
                display_remove_link(url + '#tab-' + view_name, range_.name))
        tables[view_name].rows.append(data)
    for link_ in file.get_links('P67', True):
        data = get_base_table_data(link_.domain)
        data.append(link_.description)
        if is_authorized('contributor'):
            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('link_delete',
                                 id_=link_.id,
                                 origin_id=file.id)
            data.append(
                display_remove_link(unlink_url + '#tab-reference',
                                    link_.domain.name))
        tables['reference'].rows.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)
Example #21
0
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)
Example #22
0
 def set_image_for_places(self) -> None:
     self.image_id = self.get_profile_image_id()
     if not self.image_id:
         for link_ in self.get_links('P67', inverse=True):
             domain = link_.domain
             if domain.class_.view == 'file':  # pragma: no cover
                 data = get_base_table_data(domain)
                 if data[3] in app.config['DISPLAY_FILE_EXTENSIONS']:
                     self.image_id = domain.id
                     break
def source_view(id_):
    source = EntityMapper.get_by_id(id_)
    tables = {
        'info': get_entity_data(source),
        'text': {'id': 'translation', 'data': [], 'header': ['text', 'type', 'content']},
        'file': {'id': 'files', 'data': [],
                 'header': app.config['TABLE_HEADERS']['file'] + [_('main image')]},
        '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'):
        range_ = link_.range
        data = get_base_table_data(range_)
        if is_authorized('editor'):
            url = url_for('link_delete', id_=link_.id, origin_id=source.id)
            data.append(display_remove_link(url + '#tab-' + range_.table_name, range_.name))
        tables[range_.table_name]['data'].append(data)
    profile_image_id = source.get_profile_image_id()
    for link_ in source.get_links(['P67', 'P128'], True):
        domain = link_.domain
        data = get_base_table_data(domain)
        if domain.view_name == 'file':  # pragma: no cover
            extension = data[3].replace('.', '')
            data.append(get_profile_image_table_link(domain, source, extension, profile_image_id))
            if not profile_image_id and extension in app.config['DISPLAY_FILE_EXTENSIONS']:
                profile_image_id = domain.id
        if domain.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'):
            url = url_for('link_delete', id_=link_.id, origin_id=source.id)
            data.append(display_remove_link(url + '#tab-' + domain.view_name, domain.name))
        tables[domain.view_name]['data'].append(data)
    return render_template('source/view.html', source=source, tables=tables,
                           profile_image_id=profile_image_id)
Example #24
0
def place_index() -> str:
    table = Table(Table.HEADERS['place'],
                  defs='[{className: "dt-body-right", targets: [2,3]}]')
    for place in EntityMapper.get_by_system_type(
            'place',
            nodes=True,
            aliases=current_user.settings['table_show_aliases']):
        table.rows.append(get_base_table_data(place))
    return render_template('place/index.html',
                           table=table,
                           gis_data=GisMapper.get_all())
Example #25
0
 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)
Example #26
0
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)
Example #27
0
def add_tabs_for_file(entity: Entity) -> dict[str, Tab]:
    tabs = {}
    for name in [
            'source', 'event', 'actor', 'place', 'feature',
            'stratigraphic_unit', 'artifact', 'human_remains', 'reference',
            'type']:
        tabs[name] = Tab(name, entity=entity)
    entity.image_id = entity.id if get_file_path(entity.id) else None
    for link_ in entity.get_links('P67'):
        range_ = link_.range
        data = get_base_table_data(range_)
        data.append(
            remove_link(range_.name, link_, entity, range_.class_.name))
        tabs[range_.class_.view].table.rows.append(data)
    for link_ in entity.get_links('P67', True):
        data = get_base_table_data(link_.domain)
        data.append(link_.description)
        data.append(edit_link(
            url_for('link_update', id_=link_.id, origin_id=entity.id)))
        data.append(remove_link(link_.domain.name, link_, entity, 'reference'))
        tabs['reference'].table.rows.append(data)
    return tabs
Example #28
0
    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
Example #29
0
 def __call__(self, field, **kwargs):
     selection = ''
     class_ = field.id
     if class_ in ['residence', 'begins_in', 'ends_in']:
         class_ = 'place'
     header = app.config['TABLE_HEADERS'][class_]
     table = {'id': field.id, 'header': header, 'data': []}
     file_stats = None
     if class_ == 'place':
         entities = EntityMapper.get_by_system_type('place')
     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_)
     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))
         table['data'].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">{pager}</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')),
                    pager=pager(table),
                    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
Example #30
0
 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
Example #31
0
 def __call__(self, field, **kwargs):
     selection = ''
     class_ = field.id
     if class_ in ['residence', 'appears_first', 'appears_last']:
         class_ = 'place'
     header = app.config['TABLE_HEADERS'][class_]
     table = {'id': field.id, 'header': header, 'data': []}
     if class_ == 'place':
         entities = EntityMapper.get_by_system_type('place')
     elif class_ == 'reference':
         entities = EntityMapper.get_by_system_type('bibliography') + \
                    EntityMapper.get_by_system_type('edition')
     elif class_ == 'file':
         entities = EntityMapper.get_by_system_type('file')
     else:
         entities = EntityMapper.get_by_codes(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)
         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))
         table['data'].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">{pager}</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')),
             pager=pager(table),
             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
Example #32
0
 def __call__(self, field, **kwargs):
     if field.data and isinstance(field.data, str):
         field.data = ast.literal_eval(field.data)
     selection = ''
     class_ = field.id
     if class_ in ['donor', 'recipient']:
         class_ = 'actor'
     if class_ in ['given_place']:
         class_ = 'place'
     table = {
         'id': field.id,
         'header': app.config['TABLE_HEADERS'][class_],
         'data': []}
     # 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':
         entities = EntityMapper.get_by_system_type('place')
     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] = truncate_string(entity.name)  # replace entity link with entity name
         html = """<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 '')
         data.append(html)
         table['data'].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">{pager}</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,
             pager=pager(table))
     return super(TableMultiSelect, self).__call__(field, **kwargs) + html
Example #33
0
def get_table(view: str) -> Table:
    header = g.table_headers[view]
    if view == 'file':
        header = ['date'] + header
        if session['settings']['image_processing'] \
                and current_user.settings['table_show_icons']:
            header.insert(1, _('icon'))
    table = Table(header)
    if view == 'file':
        if not g.file_stats:
            g.file_stats = get_file_stats()
        for entity in Entity.get_by_class('file', nodes=True):
            date = 'N/A'
            if entity.id in g.file_stats:
                date = format_date(
                    datetime.datetime.utcfromtimestamp(
                        g.file_stats[entity.id]['date']))
            data = [
                date,
                link(entity),
                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
            ]
            if session['settings']['image_processing'] \
                    and current_user.settings['table_show_icons']:
                data.insert(1, file_preview(entity.id))
            table.rows.append(data)

    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, aliases=True)
        table.rows = [get_base_table_data(entity) for entity in entities]
    return table
Example #34
0
def add_tabs_for_source(entity: Entity) -> dict[str, Tab]:
    tabs = {}
    for name in [
            'actor', 'artifact', 'feature', 'event', 'human_remains', 'place',
            'stratigraphic_unit', 'text'
    ]:
        tabs[name] = Tab(name, entity=entity)
    for text in entity.get_linked_entities('P73', types=True):
        tabs['text'].table.rows.append([
            link(text),
            next(iter(text.types)).name if text.types else '', text.description
        ])
    for link_ in entity.get_links('P67'):
        range_ = link_.range
        data = get_base_table_data(range_)
        data.append(remove_link(range_.name, link_, entity,
                                range_.class_.name))
        tabs[range_.class_.view].table.rows.append(data)
    return tabs
Example #35
0
def file_index():
    table = {
        'id': 'files',
        'header': app.config['TABLE_HEADERS']['file'],
        'data': []
    }
    for file in EntityMapper.get_by_system_type('file'):
        table['data'].append(get_base_table_data(file))
    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)
Example #36
0
def build_table_form(class_: str, linked_entities: list[Entity]) -> str:
    """Returns a form with a list of entities with checkboxes."""
    if class_ == 'place':
        entities = Entity.get_by_class('place', types=True, aliases=True)
    else:
        entities = Entity.get_by_view(class_, types=True, aliases=True)
    linked_ids = [entity.id for entity in linked_entities]
    table = Table([''] + g.table_headers[class_], order=[[1, 'asc']])
    for entity in entities:
        if entity.id in linked_ids:
            continue  # Don't show already linked entries
        input_ = f"""
            <input
                id="selection-{entity.id}"
                name="values"
                type="checkbox" value="{entity.id}">"""
        table.rows.append([input_] +
                          get_base_table_data(entity, show_links=False))
    if not table.rows:
        return uc_first(_('no entries'))
    return render_template('forms/form_table.html',
                           table=table.display(class_))
Example #37
0
 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
 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 = {'id': field.id, 'header': app.config['TABLE_HEADERS'][class_], 'data': []}
     # 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':
         entities = EntityMapper.get_by_system_type('place')
     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] = truncate_string(entity.name)  # Replace entity link with entity name
         html = """<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 '')
         data.append(html)
         table['data'].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">{pager}</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,
             pager=pager(table, remove_rows=False))
     return super(TableMultiSelect, self).__call__(field, **kwargs) + html
Example #39
0
def entity_view(id_: int) -> Union[str, Response]:
    if id_ in g.nodes:  # Nodes have their own view
        entity = g.nodes[id_]
        if not entity.root:
            if entity.class_.name == 'administrative_unit':
                tab_hash = '#menu-tab-places_collapse-'
            elif entity.standard:
                tab_hash = '#menu-tab-standard_collapse-'
            elif entity.value_type:
                tab_hash = '#menu-tab-value_collapse-'
            else:
                tab_hash = '#menu-tab-custom_collapse-'
            return redirect(f"{url_for('node_index')}{tab_hash}{id_}")
    elif id_ in g.reference_systems:
        entity = g.reference_systems[id_]
    else:
        entity = Entity.get_by_id(id_, nodes=True, aliases=True)
        if not entity.class_.view:
            flash(_("This entity can't be viewed directly."), 'error')
            abort(400)

    event_links = None  # Needed for actor
    overlays = None  # Needed for place
    tabs = {'info': Tab('info')}
    if isinstance(entity, Node):
        tabs['subs'] = Tab('subs', entity=entity)
        tabs['entities'] = Tab('entities', entity=entity)
        root = g.nodes[entity.root[-1]] if entity.root else None
        if root and root.value_type:  # pragma: no cover
            tabs['entities'].table.header = [
                _('name'), _('value'),
                _('class'), _('info')
            ]
        for item in entity.get_linked_entities(['P2', 'P89'],
                                               inverse=True,
                                               nodes=True):
            if item.class_.name in ['location', 'reference_system']:
                continue  # pragma: no cover
            if item.class_.name == 'object_location':  # pragma: no cover
                item = item.get_linked_entity_safe('P53', inverse=True)
            data = [link(item)]
            if root and root.value_type:  # pragma: no cover
                data.append(format_number(item.nodes[entity]))
            data.append(item.class_.label)
            data.append(item.description)
            tabs['entities'].table.rows.append(data)
        for sub_id in entity.subs:
            sub = g.nodes[sub_id]
            tabs['subs'].table.rows.append(
                [link(sub), sub.count, sub.description])
        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_entities_by_node(entity):
                tabs['entities'].table.rows.append([
                    link(Entity.get_by_id(row['domain_id'])),
                    link(Entity.get_by_id(row['range_id']))
                ])
    elif isinstance(entity, ReferenceSystem):
        for form_id, form in entity.get_forms().items():
            tabs[form['name']] = Tab(form['name'], entity=entity)
            tabs[form['name']].table = \
                Table([_('entity'), 'id', _('precision')])
        for link_ in entity.get_links('P67'):
            name = link_.description
            if entity.resolver_url:
                name = \
                    f'<a href="{entity.resolver_url + name}"' \
                    f' target="_blank" rel="noopener noreferrer">{name}</a>'
            tab_name = link_.range.class_.name
            tabs[tab_name].table.rows.append(
                [link(link_.range), name, link_.type.name])
        for form_id, form in entity.get_forms().items():
            tabs[form['name']].buttons = []
            if not tabs[form['name']].table.rows and is_authorized('manager'):
                tabs[form['name']].buttons = [
                    button(
                        _('remove'),
                        url_for('reference_system_remove_form',
                                system_id=entity.id,
                                form_id=form_id))
                ]
    elif entity.class_.view == 'actor':
        for name in [
                'source', 'event', 'relation', 'member_of', 'member',
                'artifact'
        ]:
            tabs[name] = Tab(name, entity=entity)
        event_links = entity.get_links(['P11', 'P14', 'P22', 'P23', 'P25'],
                                       True)
        for link_ in event_links:
            event = link_.domain
            places = event.get_linked_entities(['P7', 'P26', 'P27'])
            link_.object_ = None  # Needed for first/last appearance
            for place in places:
                object_ = place.get_linked_entity_safe('P53', True)
                entity.linked_places.append(object_)
                link_.object_ = object_
            first = link_.first
            if not link_.first and event.first:
                first = f'<span class="inactive">{event.first}</span>'
            last = link_.last
            if not link_.last and event.last:
                last = f'<span class="inactive">{event.last}</span>'
            data = [
                link(event), event.class_.label,
                _('moved') if link_.property.code == 'P25' else link(
                    link_.type), first, last, link_.description
            ]
            if link_.property.code == 'P25':
                data += ['']
            else:
                add_edit_link(
                    data,
                    url_for('involvement_update',
                            id_=link_.id,
                            origin_id=entity.id))
            add_remove_link(data, link_.domain.name, link_, entity, 'event')
            tabs['event'].table.rows.append(data)
        for link_ in entity.get_links('OA7') + entity.get_links('OA7', True):
            type_ = ''
            if entity.id == link_.domain.id:
                related = link_.range
                if link_.type:
                    type_ = link(link_.type.get_name_directed(),
                                 url_for('entity_view', id_=link_.type.id))
            else:
                related = link_.domain
                if link_.type:
                    type_ = link(link_.type.get_name_directed(True),
                                 url_for('entity_view', id_=link_.type.id))
            data = [
                type_,
                link(related), link_.first, link_.last, link_.description
            ]
            add_edit_link(
                data,
                url_for('relation_update', id_=link_.id, origin_id=entity.id))
            add_remove_link(data, related.name, link_, entity, 'relation')
            tabs['relation'].table.rows.append(data)
        for link_ in entity.get_links('P107', True):
            data = [
                link(link_.domain),
                link(link_.type), link_.first, link_.last, link_.description
            ]
            add_edit_link(
                data,
                url_for('member_update', id_=link_.id, origin_id=entity.id))
            add_remove_link(data, link_.domain.name, link_, entity,
                            'member-of')
            tabs['member_of'].table.rows.append(data)
        if entity.class_.name != 'group':
            del tabs['member']
        else:
            for link_ in entity.get_links('P107'):
                data = [
                    link(link_.range),
                    link(link_.type), link_.first, link_.last,
                    link_.description
                ]
                add_edit_link(
                    data,
                    url_for('member_update', id_=link_.id,
                            origin_id=entity.id))
                add_remove_link(data, link_.range.name, link_, entity,
                                'member')
                tabs['member'].table.rows.append(data)
        for link_ in entity.get_links('P52', True):
            data = [
                link(link_.domain), link_.domain.class_.label,
                link(link_.domain.standard_type), link_.domain.first,
                link_.domain.last, link_.domain.description
            ]
            tabs['artifact'].table.rows.append(data)
    elif entity.class_.view == 'artifact':
        tabs['source'] = Tab('source', entity=entity)
    elif entity.class_.view == 'event':
        for name in ['subs', 'source', 'actor']:
            tabs[name] = Tab(name, entity=entity)
        for sub_event in entity.get_linked_entities('P117',
                                                    inverse=True,
                                                    nodes=True):
            tabs['subs'].table.rows.append(get_base_table_data(sub_event))
        tabs['actor'].table.header.insert(5, _('activity'))  # Activity column
        for link_ in entity.get_links(['P11', 'P14', 'P22', 'P23']):
            first = link_.first
            if not link_.first and entity.first:
                first = f'<span class="inactive">{entity.first}</span>'
            last = link_.last
            if not link_.last and entity.last:
                last = f'<span class="inactive">{entity.last}</span>'
            data = [
                link(link_.range), link_.range.class_.label,
                link_.type.name if link_.type else '', first, last,
                g.properties[link_.property.code].name_inverse,
                link_.description
            ]
            add_edit_link(
                data,
                url_for('involvement_update',
                        id_=link_.id,
                        origin_id=entity.id))
            add_remove_link(data, link_.range.name, link_, entity, 'actor')
            tabs['actor'].table.rows.append(data)
        entity.linked_places = [
            location.get_linked_entity_safe('P53', True)
            for location in entity.get_linked_entities(['P7', 'P26', 'P27'])
        ]
    elif entity.class_.view == 'file':
        for name in [
                'source', 'event', 'actor', 'place', 'feature',
                'stratigraphic_unit', 'artifact', 'human_remains', 'reference',
                'type'
        ]:
            tabs[name] = Tab(name, entity=entity)
        entity.image_id = entity.id if get_file_path(entity.id) else None
        for link_ in entity.get_links('P67'):
            range_ = link_.range
            data = get_base_table_data(range_)
            add_remove_link(data, range_.name, link_, entity,
                            range_.class_.name)
            tabs[range_.class_.view].table.rows.append(data)
        for link_ in entity.get_links('P67', True):
            data = get_base_table_data(link_.domain)
            data.append(link_.description)
            add_edit_link(
                data,
                url_for('reference_link_update',
                        link_id=link_.id,
                        origin_id=entity.id))
            add_remove_link(data, link_.domain.name, link_, entity,
                            'reference')
            tabs['reference'].table.rows.append(data)
    elif entity.class_.view == 'place':
        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['find'] = Tab('find', entity=entity)
            tabs['human_remains'] = Tab('human_remains', entity=entity)
        entity.location = entity.get_linked_entity_safe('P53', nodes=True)
        event_ids = []  # Keep track of inserted events to prevent doubles
        for event in entity.location.get_linked_entities(['P7', 'P26', 'P27'],
                                                         inverse=True):
            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))
        if 'actor' in tabs:
            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
                ])
    elif entity.class_.view == 'reference':
        for name in [
                'source', 'event', 'actor', 'place', 'feature',
                'stratigraphic_unit', 'human_remains', 'artifact', 'file'
        ]:
            tabs[name] = Tab(name, entity=entity)
        for link_ in entity.get_links('P67'):
            range_ = link_.range
            data = get_base_table_data(range_)
            data.append(link_.description)
            add_edit_link(
                data,
                url_for('reference_link_update',
                        link_id=link_.id,
                        origin_id=entity.id))
            add_remove_link(data, range_.name, link_, entity,
                            range_.class_.name)
            tabs[range_.class_.view].table.rows.append(data)
    elif entity.class_.view == 'source':
        for name in [
                'actor', 'artifact', 'feature', 'event', 'human_remains',
                'place', 'stratigraphic_unit', 'text'
        ]:
            tabs[name] = Tab(name, entity=entity)
        for text in entity.get_linked_entities('P73', nodes=True):
            tabs['text'].table.rows.append([
                link(text),
                next(iter(text.nodes)).name if text.nodes else '',
                text.description
            ])
        for link_ in entity.get_links('P67'):
            range_ = link_.range
            data = get_base_table_data(range_)
            add_remove_link(data, range_.name, link_, entity,
                            range_.class_.name)
            tabs[range_.class_.view].table.rows.append(data)

    if entity.class_.view in [
            'actor', 'artifact', 'event', 'place', 'source', 'type'
    ]:
        if entity.class_.view != 'reference' and not isinstance(entity, Node):
            tabs['reference'] = Tab('reference', entity=entity)
        if entity.class_.view == 'artifact':
            tabs['event'] = Tab('event', entity=entity)
            for link_ in entity.get_links('P25', True):
                data = get_base_table_data(link_.domain)
                tabs['event'].table.rows.append(data)
        tabs['file'] = Tab('file', entity=entity)
        entity.image_id = entity.get_profile_image_id()
        if entity.class_.view == 'place' and is_authorized('editor') and \
                current_user.settings['module_map_overlay']:
            tabs['file'].table.header.append(uc_first(_('overlay')))
        for link_ in entity.get_links('P67', inverse=True):
            domain = link_.domain
            data = get_base_table_data(domain)
            if domain.class_.view == 'file':  # pragma: no cover
                extension = data[3]
                data.append(
                    get_profile_image_table_link(domain, entity, extension,
                                                 entity.image_id))
                if not entity.image_id \
                        and extension in app.config['DISPLAY_FILE_EXTENSIONS']:
                    entity.image_id = domain.id
                if entity.class_.view == 'place' \
                        and is_authorized('editor') \
                        and current_user.settings['module_map_overlay']:
                    overlays = Overlay.get_by_object(entity)
                    if extension in app.config['DISPLAY_FILE_EXTENSIONS']:
                        if domain.id in overlays:
                            add_edit_link(
                                data,
                                url_for('overlay_update',
                                        id_=overlays[domain.id].id))
                        else:
                            data.append(
                                link(
                                    _('link'),
                                    url_for('overlay_insert',
                                            image_id=domain.id,
                                            place_id=entity.id,
                                            link_id=link_.id)))
                    else:  # pragma: no cover
                        data.append('')
            if domain.class_.view not in ['source', 'file']:
                data.append(link_.description)
                add_edit_link(
                    data,
                    url_for('reference_link_update',
                            link_id=link_.id,
                            origin_id=entity.id))
                if domain.class_.view == 'reference_system':
                    entity.reference_systems.append(link_)
                    continue
            add_remove_link(data, domain.name, link_, entity,
                            domain.class_.view)
            tabs[domain.class_.view].table.rows.append(data)

    structure = None  # Needed for place
    gis_data = None  # Needed for place
    if entity.class_.view in ['artifact', 'place']:
        structure = get_structure(entity)
        if structure:
            for item in structure['subunits']:
                tabs[item.class_.name].table.rows.append(
                    get_base_table_data(item))
        gis_data = Gis.get_all([entity], structure)
        if gis_data['gisPointSelected'] == '[]' \
                and gis_data['gisPolygonSelected'] == '[]' \
                and gis_data['gisLineSelected'] == '[]' \
                and (not structure or not structure['super_id']):
            gis_data = {}

    if not gis_data:
        gis_data = Gis.get_all(entity.linked_places) \
            if entity.linked_places else None
    entity.info_data = get_entity_data(entity, event_links=event_links)
    tabs['note'] = Tab('note', entity=entity)
    for note in current_user.get_notes_by_entity_id(entity.id):
        data = [
            format_date(note['created']),
            uc_first(_('public'))
            if note['public'] else uc_first(_('private')),
            link(User.get_by_id(note['user_id'])), note['text'],
            f'<a href="{url_for("note_view", id_=note["id"])}">'
            f'{uc_first(_("view"))}</a>'
        ]
        tabs['note'].table.rows.append(data)
    if 'file' in tabs and current_user.settings['table_show_icons'] and \
            session['settings']['image_processing']:
        tabs['file'].table.header.insert(1, uc_first(_('icon')))
        for row in tabs['file'].table.rows:
            row.insert(
                1,
                file_preview(
                    int(row[0].replace('<a href="/entity/',
                                       '').split('"')[0])))
    tabs['info'].content = render_template(
        'entity/view.html',
        buttons=add_buttons(entity),
        entity=entity,
        gis_data=gis_data,
        structure=structure,  # Needed for place views
        overlays=overlays,  # Needed for place views
        title=entity.name)
    return render_template('tabs.html',
                           tabs=tabs,
                           gis_data=gis_data,
                           crumbs=add_crumbs(entity, structure),
                           entity=entity)
def actor_view(id_):
    actor = EntityMapper.get_by_id(id_)
    actor.set_dates()
    objects = []
    info = get_entity_data(actor)
    residence = actor.get_linked_entity('P74')
    if residence:
        object_ = residence.get_linked_entity('P53', True)
        objects.append(object_)
        info.append((uc_first(_('residence')), link(object_)))
    first = actor.get_linked_entity('OA8')
    if first:
        object_ = first.get_linked_entity('P53', True)
        objects.append(object_)
        info.append((uc_first(_('appears first')), link(object_)))
    last = actor.get_linked_entity('OA9')
    if last:
        object_ = last.get_linked_entity('P53', True)
        objects.append(object_)
        info.append((uc_first(_('appears last')), link(object_)))
    tables = {
        'info': info,
        'file': {'id': 'files', 'data': [],
                 'header': app.config['TABLE_HEADERS']['file'] + [_('main image')]},
        'source': {'id': 'source', 'data': [], 'header': app.config['TABLE_HEADERS']['source']},
        'reference': {'id': 'reference', 'data': [],
                      'header': app.config['TABLE_HEADERS']['reference'] + ['pages']},
        'event': {'id': 'event', 'data': [],
                  'header': ['event', 'class', 'involvement', 'first', 'last', 'description']},
        'relation': {'id': 'relation', 'data': [], 'sort': 'sortList:[[0,0]]',
                     'header': ['relation', 'actor', 'first', 'last', 'description']},
        'member_of': {'id': 'member_of', 'data': [],
                      'header': ['member of', 'function', 'first', 'last', 'description']}}
    profile_image_id = actor.get_profile_image_id()
    for link_ in actor.get_links('P67', True):
        domain = link_.domain
        data = get_base_table_data(domain)
        if domain.view_name == 'file':
            extension = data[3].replace('.', '')
            data.append(get_profile_image_table_link(domain, actor, extension, profile_image_id))
            if not profile_image_id and extension in app.config['DISPLAY_FILE_EXTENSIONS']:
                profile_image_id = domain.id
        if domain.view_name not in ['source', 'file']:
            data.append(truncate_string(link_.description))
            if is_authorized('editor'):
                update_url = url_for('reference_link_update', link_id=link_.id, origin_id=actor.id)
                data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>')
        if is_authorized('editor'):
            url = url_for('link_delete', id_=link_.id, origin_id=actor.id)
            data.append(display_remove_link(url + '#tab-' + domain.view_name, domain.name))
        tables[domain.view_name]['data'].append(data)

    # Todo: Performance - getting every place of every object for every event is very costly
    for link_ in actor.get_links(['P11', 'P14', 'P22', 'P23'], True):
        event = link_.domain
        first = link_.first
        place = event.get_linked_entity('P7')
        if place:
            objects.append(place.get_linked_entity('P53', True))
        if not link_.first and event.first:
            first = '<span class="inactive" style="float:right">' + str(event.first) + '</span>'
        last = link_.last
        if not link_.last and event.last:
            last = '<span class="inactive" style="float:right">' + str(event.last) + '</span>'
        data = ([link(event),
                 g.classes[event.class_.code].name,
                 link_.type.name if link_.type else '',
                 first,
                 last,
                 truncate_string(link_.description)])
        if is_authorized('editor'):
            update_url = url_for('involvement_update', id_=link_.id, origin_id=actor.id)
            unlink_url = url_for('link_delete', id_=link_.id, origin_id=actor.id) + '#tab-event'
            data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>')
            data.append(display_remove_link(unlink_url, link_.domain.name))
        tables['event']['data'].append(data)
    for link_ in actor.get_links('OA7') + actor.get_links('OA7', True):
        if actor.id == link_.domain.id:
            type_ = link_.type.get_name_directed() if link_.type else ''
            related = link_.range
        else:
            type_ = link_.type.get_name_directed(True) if link_.type else ''
            related = link_.domain
        data = ([type_, link(related), link_.first, link_.last, truncate_string(link_.description)])
        if is_authorized('editor'):
            update_url = url_for('relation_update', id_=link_.id, origin_id=actor.id)
            unlink_url = url_for('link_delete', id_=link_.id, origin_id=actor.id) + '#tab-relation'
            data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>')
            data.append(display_remove_link(unlink_url, related.name))
        tables['relation']['data'].append(data)
    for link_ in actor.get_links('P107', True):
        data = ([link(link_.domain),
                 link_.type.name if link_.type else '',
                 link_.first,
                 link_.last,
                 truncate_string(link_.description)])
        if is_authorized('editor'):
            update_url = url_for('member_update', id_=link_.id, origin_id=actor.id)
            unlink_url = url_for('link_delete', id_=link_.id, origin_id=actor.id) + '#tab-member-of'
            data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>')
            data.append(display_remove_link(unlink_url, link_.domain.name))
        tables['member_of']['data'].append(data)
    if actor.class_.code in app.config['CLASS_CODES']['group']:
        tables['member'] = {'id': 'member', 'data': [],
                            'header': ['member', 'function', 'first', 'last', 'description']}
        for link_ in actor.get_links('P107'):
            data = ([link(link_.range),
                     link_.type.name if link_.type else '',
                     link_.first,
                     link_.last,
                     truncate_string(link_.description)])
            if is_authorized('editor'):
                update_url = url_for('member_update', id_=link_.id, origin_id=actor.id)
                unlink_url = url_for('link_delete', id_=link_.id,
                                     origin_id=actor.id) + '#tab-member'
                data.append('<a href="' + update_url + '">' + uc_first(_('edit')) + '</a>')
                data.append(display_remove_link(unlink_url, link_.range.name))
            tables['member']['data'].append(data)
    gis_data = GisMapper.get_all(objects) if objects else None
    if gis_data and gis_data['gisPointSelected'] == '[]':
        gis_data = None
    return render_template('actor/view.html', actor=actor, tables=tables, gis_data=gis_data,
                           profile_image_id=profile_image_id)
def source_index():
    table = {'id': 'source', 'header': app.config['TABLE_HEADERS']['source'], 'data': []}
    for source in EntityMapper.get_by_codes('source'):
        data = get_base_table_data(source)
        table['data'].append(data)
    return render_template('source/index.html', table=table)
Example #42
0
def place_view(id_: int) -> str:
    object_ = EntityMapper.get_by_id(id_, nodes=True, aliases=True)
    object_.note = UserMapper.get_note(object_)
    location = object_.get_linked_entity('P53', nodes=True)
    tables = {
        'info':
        get_entity_data(object_, location),
        'file':
        Table(Table.HEADERS['file'] + [_('main image')]),
        'source':
        Table(Table.HEADERS['source']),
        'event':
        Table(Table.HEADERS['event'],
              defs='[{className: "dt-body-right", targets: [3,4]}]'),
        'reference':
        Table(Table.HEADERS['reference'] + ['page / link text']),
        'actor':
        Table([_('actor'),
               _('property'),
               _('class'),
               _('first'),
               _('last')])
    }
    if object_.system_type == 'place':
        tables['feature'] = Table(Table.HEADERS['place'] + [_('description')])
    if object_.system_type == 'feature':
        tables['stratigraphic-unit'] = Table(Table.HEADERS['place'] +
                                             [_('description')])
    if object_.system_type == 'stratigraphic unit':
        tables['find'] = Table(Table.HEADERS['place'] + [_('description')])
    profile_image_id = object_.get_profile_image_id()
    overlays = None
    if current_user.settings['module_map_overlay']:
        overlays = OverlayMapper.get_by_object(object_)
        if is_authorized('editor'):
            tables['file'].header.append(uc_first(_('overlay')))

    for link_ in object_.get_links('P67', inverse=True):
        domain = link_.domain
        data = get_base_table_data(domain)
        if domain.view_name == 'file':
            extension = data[3].replace('.', '')
            data.append(
                get_profile_image_table_link(domain, object_, extension,
                                             profile_image_id))
            if not profile_image_id and extension in app.config[
                    'DISPLAY_FILE_EXTENSIONS']:
                profile_image_id = domain.id
            if is_authorized(
                    'editor') and current_user.settings['module_map_overlay']:
                if extension in app.config['DISPLAY_FILE_EXTENSIONS']:
                    if domain.id in overlays:
                        url = url_for('overlay_update',
                                      id_=overlays[domain.id].id)
                        data.append('<a href="' + url + '">' +
                                    uc_first(_('edit')) + '</a>')
                    else:
                        url = url_for('overlay_insert',
                                      image_id=domain.id,
                                      place_id=object_.id,
                                      link_id=link_.id)
                        data.append('<a href="' + url + '">' +
                                    uc_first(_('add')) + '</a>')
                else:  # pragma: no cover
                    data.append('')
        if domain.view_name not in ['source', 'file']:
            data.append(truncate_string(link_.description))
            if domain.system_type.startswith('external reference'):
                object_.external_references.append(link_)
            if is_authorized(
                    'contributor'
            ) and domain.system_type != 'external reference geonames':
                url = url_for('reference_link_update',
                              link_id=link_.id,
                              origin_id=object_.id)
                data.append('<a href="' + url + '">' + uc_first(_('edit')) +
                            '</a>')
            else:
                data.append('')
        if is_authorized('contributor'):
            url = url_for('link_delete', id_=link_.id, origin_id=object_.id)
            data.append(
                display_remove_link(url + '#tab-' + domain.view_name,
                                    domain.name))
        tables[domain.view_name].rows.append(data)
    event_ids = []  # Keep track of already inserted events to prevent doubles
    for event in location.get_linked_entities(['P7', 'P26', 'P27'],
                                              inverse=True):
        tables['event'].rows.append(get_base_table_data(event))
        event_ids.append(event.id)
    for event in object_.get_linked_entities(['P24'], inverse=True):
        if event.id not in event_ids:  # Don't add again if already in table
            tables['event'].rows.append(get_base_table_data(event))
    has_subunits = False
    for entity in object_.get_linked_entities('P46', nodes=True):
        has_subunits = True
        data = get_base_table_data(entity)
        data.append(truncate_string(entity.description))
        tables[entity.system_type.replace(' ', '-')].rows.append(data)
    for link_ in location.get_links(['P74', 'OA8', 'OA9'], inverse=True):
        actor = EntityMapper.get_by_id(link_.domain.id)
        tables['actor'].rows.append([
            link(actor), g.properties[link_.property.code].name,
            actor.class_.name, actor.first, actor.last
        ])
    gis_data = GisMapper.get_all(object_) if location else None
    if gis_data['gisPointSelected'] == '[]' and gis_data['gisPolygonSelected'] == '[]' \
            and gis_data['gisLineSelected'] == '[]':
        gis_data = None
    place = None
    feature = None
    stratigraphic_unit = None
    if object_.system_type == 'find':
        stratigraphic_unit = object_.get_linked_entity('P46', True)
        feature = stratigraphic_unit.get_linked_entity('P46', True)
        place = feature.get_linked_entity('P46', True)
    elif object_.system_type == 'stratigraphic unit':
        feature = object_.get_linked_entity('P46', True)
        place = feature.get_linked_entity('P46', True)
    elif object_.system_type == 'feature':
        place = object_.get_linked_entity('P46', True)
    return render_template('place/view.html',
                           object_=object_,
                           tables=tables,
                           gis_data=gis_data,
                           place=place,
                           feature=feature,
                           stratigraphic_unit=stratigraphic_unit,
                           has_subunits=has_subunits,
                           profile_image_id=profile_image_id,
                           overlays=overlays)