Exemple #1
0
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')])
Exemple #2
0
def get_vax_trends(area=None):
    """
    Return the vax-trends array
    :param area: optional, str
    :return: list of dicts
    """
    data = get_vax_trends_data(area)
    trends = []
    for d in VAX_DOSES:
        last_week_dt = data[6]['_id']
        count = data[0][d]
        last_week_count = data[6][d]
        diff = count - last_week_count
        if diff > 0:
            status = 'increase'
        elif diff < 0:
            status = 'decrease'
        else:
            status = 'stable'
        try:
            perc = f'{round(diff / last_week_count * 100)}%'
        except (ValueError, ZeroDivisionError):
            perc = 'n/a'
        trends.append({
            'id': d,
            'last_week_count': format_number(last_week_count),
            'percentage': perc,
            'title': VARS[d]['title'],
            'colour': VARS[d][status]['colour'],
            "icon": VARS[d]['icon'],
            'status_icon': VARS[d][status]['icon'],
            'count': format_number(count),
            'last_week_dt': format_datetime(last_week_dt, DOW_FMTY)
        })
    return trends
Exemple #3
0
def format_trends(trends):
    """In-place format count and last week count"""
    try:
        for t in trends:
            t['count'] = format_number(t['count'])
            t['last_week_count'] = format_number(t['last_week_count'])
            t['last_week_dt'] = format_datetime(t['last_week_dt'], DOW_FMTY)
    except Exception as e:
        app.logger.error(f'While formatting trends: {e}')
        pass
    return trends
Exemple #4
0
def add_type_data(entity: 'Entity', data: Dict[str, Any]) -> Dict[str, Any]:
    if entity.location:
        entity.nodes.update(entity.location.nodes)  # Add location types
    type_data: OrderedDict[str, Any] = OrderedDict()
    for node, node_value in entity.nodes.items():
        root = g.nodes[node.root[-1]]
        label = 'type' if root.standard and root.class_.name == 'type' else root.name
        if root.name not in type_data:
            type_data[label] = []
        text = ''
        if root.value_type:  # Text for value types
            text = ': {value} <span style="font-style:italic;">{description}</span>'.format(
                value=format_number(node_value), description=node.description)
        type_data[label].append(
            '<span title="{path}">{link}</span>{text}'.format(
                link=link(node),
                path=' > '.join([g.nodes[id_].name for id_ in node.root]),
                text=text))

    # Sort types by name
    for root_type in type_data:
        type_data[root_type].sort()

    # Move the standard type to the top
    if 'type' in type_data:
        type_data.move_to_end('type', last=False)
    for root_name, nodes in type_data.items():
        data[root_name] = nodes
    return data
Exemple #5
0
def add_type_data(entity, data, location=None):
    type_data = OrderedDict()
    # Nodes
    if location:
        entity.nodes.update(location.nodes)  # Add location types
    for node, node_value in entity.nodes.items():
        root = g.nodes[node.root[-1]]
        name = 'type' if root.name in app.config['BASE_TYPES'] else root.name
        if root.name not in type_data:
            type_data[name] = []
        text = ''
        if root.value_type:  # Text for value types
            text = ': {value} <span style="font-style:italic;">{description}</span>'.format(
                value=format_number(node_value), description=node.description)
        type_data[name].append(link(node) + text)

    # Sort types by name
    type_data = OrderedDict(sorted(type_data.items(), key=lambda t: t[0]))
    for root_type in type_data:
        type_data[root_type].sort()

    # Move the base type to the top
    if 'type' in type_data:
        type_data.move_to_end('type', last=False)
    for root_name, nodes in type_data.items():
        data.append((root_name, '<br />'.join(nodes)))
    return data
Exemple #6
0
def regional_view(region):
    """
    Render the regional view
    :param region: str: region
    :return: template
    """
    data_type = "regional"
    if region not in REGIONS:
        error = f'Area {region} not found'
        return render_template("errors/404.html", error=error)
    cards = get_regional_trends(region)
    breakdown = get_provincial_breakdown(region=region)
    series = get_regional_series(region=region)
    notes = get_notes(notes_type=data_type, area=region)
    latest_update = get_latest_update(data_type=data_type)
    positivity_idx = get_positivity_idx(area_type=data_type, area=region)
    provinces = ITALY_MAP[region]
    population = get_area_population(region)
    view_data = dict(ts=int(time.time()),
                     page_title=f"{PAGE_BASE_TITLE} | {region}",
                     dashboard_title=region,
                     region=region,
                     region_provinces=provinces,
                     trend_cards=cards,
                     breakdown=breakdown,
                     positivity_idx=positivity_idx,
                     series=series,
                     notes=notes,
                     latest_update=latest_update,
                     data_type=data_type,
                     cards=cards,
                     population=format_number(population))
    dashboard_data = enrich_frontend_data(area=region, **view_data)
    return render_template("pandemic.html", **dashboard_data)
Exemple #7
0
def add_tabs_for_type(entity: Type) -> dict[str, Tab]:
    tabs = {
        'subs': Tab('subs', entity=entity),
        'entities': Tab('entities', entity=entity)}
    for sub_id in entity.subs:
        sub = g.types[sub_id]
        tabs['subs'].table.rows.append([
            link(sub),
            sub.count,
            sub.description])
    if entity.category == 'value':
        tabs['entities'].table.header = \
            [_('name'), _('value'), _('class'), _('info')]
    for item in entity.get_linked_entities(
            ['P2', 'P89'],
            inverse=True,
            types=True):
        if item.class_.name in ['location', 'reference_system']:
            continue  # pragma: no cover
        if item.class_.name == 'object_location':
            item = item.get_linked_entity_safe('P53', inverse=True)
        data = [link(item)]
        if entity.category == 'value':
            data.append(format_number(item.types[entity]))
        data.append(item.class_.label)
        data.append(item.description)
        tabs['entities'].table.rows.append(data)
    if not tabs['entities'].table.rows:
        # If no entities available get links with this type_id
        tabs['entities'].table.header = [_('domain'), _('range')]
        for row in Link.get_links_by_type(entity):
            tabs['entities'].table.rows.append([
                link(Entity.get_by_id(row['domain_id'])),
                link(Entity.get_by_id(row['range_id']))])
    return tabs
Exemple #8
0
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)
Exemple #9
0
def hierarchy_update(id_: int) -> Union[str, Response]:
    hierarchy = g.nodes[id_]
    if hierarchy.standard:
        abort(403)
    form = build_form('hierarchy', hierarchy)
    form.forms.choices = Node.get_form_choices(hierarchy)
    if hasattr(form, 'multiple') and form.multiple.data:
        form.multiple.render_kw = {'disabled': 'disabled'}
    if form.validate_on_submit():
        if form.name.data != hierarchy.name and Node.get_nodes(form.name.data):
            flash(_('error name exists'), 'error')
        else:
            save(form, hierarchy)
            flash(_('info update'), 'info')
        tab = 'value' if g.nodes[id_].value_type else 'custom'
        return redirect(
            f"{url_for('node_index')}#menu-tab-{tab}_collapse-{hierarchy.id}")
    form.multiple = hierarchy.multiple
    table = Table(paging=False)
    for form_id, form_ in hierarchy.forms.items():
        count = Node.get_form_count(hierarchy, form_id)
        table.rows.append([
            g.classes[form_['name']].label,
            format_number(count) if count else link(
                _('remove'),
                url_for('remove_form', id_=hierarchy.id, form_id=form_id))
        ])
    return render_template('display_form.html',
                           form=form,
                           table=table,
                           manual_page='entity/type',
                           title=_('types'),
                           crumbs=[[_('types'),
                                    url_for('node_index')], hierarchy,
                                   _('edit')])
def walk_tree(param):
    text = ''
    for id_ in param if type(param) is list else [param]:
        item = g.nodes[id_]
        count_subs = ' (' + format_number(item.count_subs) + ')' if item.count_subs else ''
        text += "{href: '" + url_for('node_view', id_=item.id) + "',"
        text += "text: '" + item.name.replace("'", "&apos;") + " "
        text += '<span style="font-weight:normal">' + format_number(item.count) + count_subs
        text += "', 'id':'" + str(item.id) + "'"
        if item.subs:
            text += ",'children' : ["
            for sub in item.subs:
                text += walk_tree(sub)
            text += "]"
        text += "},"
    return text
Exemple #11
0
def national_view():
    """
    Render the national view
    :return: template
    """
    data_type = "national"
    cards = get_national_trends()
    breakdown = get_regional_breakdown()
    series = get_national_series()
    notes = get_notes(notes_type=data_type)
    updated_at = get_latest_update(data_type=data_type)
    positivity_idx = get_positivity_idx(area_type=data_type)
    population = get_area_population()
    data = enrich_frontend_data(page_title=PAGE_BASE_TITLE,
                                dashboard_title=gettext("Italy"),
                                ts=int(time.time()),
                                trend_cards=cards,
                                series=series,
                                latest_update=updated_at,
                                breakdown=breakdown,
                                positivity_idx=positivity_idx,
                                data_type=data_type,
                                notes=notes,
                                population=format_number(population))
    return render_template("pandemic.html", **data)
def index():
    tables = {
        'counts': {'id': 'overview', 'header': [], 'data': [], 'show_pager': False},
        'bookmarks': {'id': 'bookmarks', 'data': [], 'show_pager': False,
                      'header': ['name', 'class', 'first', 'last']},
        'latest': {'id': 'latest', 'data': [], 'show_pager': False,
                   'header': ['name', 'class', 'first', 'last', 'date', 'user']}}
    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']['data'].append([
                link(entity),
                g.classes[entity.class_.code].name,
                entity.first,
                entity.last,
                bookmark_toggle(entity.id, True)])
        for name, count in EntityMapper.get_overview_counts().items():
            count = format_number(count) if count else ''
            tables['counts']['data'].append([
                '<a href="' + url_for(name + '_index') + '">' + uc_first(_(name)) + '</a>', count])
        for entity in EntityMapper.get_latest(8):
            tables['latest']['data'].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)
Exemple #13
0
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')])
Exemple #14
0
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 hierarchy_update(id_):
    root = g.nodes[id_]
    if root.system:
        abort(403)
    form = build_form(HierarchyForm, 'hierarchy', root)
    form.forms.choices = NodeMapper.get_form_choices(root)
    if root.value_type:
        del form.multiple
    elif root.multiple:
        form.multiple.render_kw = {'disabled': 'disabled'}
    if form.validate_on_submit():
        if form.name.data != root.name and NodeMapper.get_nodes(form.name.data):
            flash(_('error name exists'), 'error')
            return redirect(url_for('node_index') + '#tab-' + str(root.id))
        save(form, root)
        flash(_('info update'), 'info')
        return redirect(url_for('node_index') + '#tab-' + str(root.id))
    form.multiple = root.multiple
    table = {'id': 'used_forms', 'show_pager': False, 'data': [], 'sort': 'sortList: [[0, 0]]',
             'header': ['form', 'count']}
    for form_id, form_ in root.forms.items():
        url = url_for('hierarchy_remove_form', id_=root.id, remove_id=form_id)
        link = '<a href="' + url + '">' + uc_first(_('remove')) + '</a>'
        count = NodeMapper.get_form_count(root, form_id)
        table['data'].append([form_['name'], format_number(count) if count else link])
    return render_template('hierarchy/update.html', node=root, form=form, table=table,
                           forms=[form.id for form in form.forms])
Exemple #16
0
def hierarchy_update(id_: int) -> str:
    root = g.nodes[id_]
    if root.system:
        abort(403)
    form = build_form(HierarchyForm, 'hierarchy', root)  # type: HierarchyForm
    form.forms.choices = NodeMapper.get_form_choices(root)
    if root.value_type:
        del form.multiple
    elif root.multiple:
        form.multiple.render_kw = {'disabled': 'disabled'}
    if form.validate_on_submit():
        if form.name.data != root.name and NodeMapper.get_nodes(form.name.data):
            flash(_('error name exists'), 'error')
            return redirect(url_for('node_index') + '#tab-' + str(root.id))
        save(form, root)
        flash(_('info update'), 'info')
        return redirect(url_for('node_index') + '#tab-' + str(root.id))
    form.multiple = root.multiple
    table = Table(['form', 'count'], paging=False)
    for form_id, form_ in root.forms.items():
        url = url_for('hierarchy_remove_form', id_=root.id, remove_id=form_id)
        link = '<a href="' + url + '">' + uc_first(_('remove')) + '</a>'
        count = NodeMapper.get_form_count(root, form_id)
        table.rows.append([form_['name'], format_number(count) if count else link])
    return render_template('hierarchy/update.html', node=root, form=form, table=table,
                           forms=[form.id for form in form.forms])
def node_view(id_):
    from openatlas.models.linkProperty import LinkPropertyMapper
    node = g.nodes[id_]
    root = g.nodes[node.root[-1]] if node.root else None
    super_ = g.nodes[node.root[0]] if node.root else None
    header = [_('name'), _('class'), _('info')]
    if root and root.value_type:  # pragma: no cover
        header = [_('name'), _('value'), _('class'), _('info')]
    tables = {'entities': {'id': 'entities', 'header': header, 'data': []},
              'info': get_entity_data(node)}

    for entity in node.get_linked_entities(['P2', 'P89'], True):
        # If it is a place location get the corresponding object
        entity = entity if node.class_.code == 'E55' else entity.get_linked_entity('P53', True)
        if entity:  # If not entity it is a place node, so do not add
            data = [link(entity)]
            if root and root.value_type:  # pragma: no cover
                data.append(format_number(entity.nodes[node]))
            data.append(g.classes[entity.class_.code].name)
            data.append(truncate_string(entity.description))
            tables['entities']['data'].append(data)
    tables['link_entities'] = {'id': 'link_items', 'header': [_('domain'), _('range')], 'data': []}
    for row in LinkPropertyMapper.get_entities_by_node(node):
        tables['link_entities']['data'].append([link(EntityMapper.get_by_id(row.domain_id)),
                                                link(EntityMapper.get_by_id(row.range_id))])
    tables['subs'] = {'id': 'subs', 'header': [_('name'), _('count'), _('info')], 'data': []}
    for sub_id in node.subs:
        sub = g.nodes[sub_id]
        tables['subs']['data'].append([link(sub), sub.count, truncate_string(sub.description)])
    return render_template('types/view.html', node=node, super_=super_, tables=tables, root=root)
Exemple #18
0
def index():
    # Popular reviews
    popular_reviews = db_review.get_popular(6)
    for review in popular_reviews:
        # Preparing text for preview
        preview = markdown(review['text'], safe_mode="escape")
        review['preview'] = ''.join(BeautifulSoup(preview, "html.parser").findAll(text=True))

    # Recent reviews
    recent_reviews, _ = db_review.list_reviews(sort='published_on', limit=9)

    # Statistics
    review_count = format_number(db_review.get_count(is_draft=False))
    user_count = format_number(db_users.total_count())

    return render_template('index/index.html', popular_reviews=popular_reviews, recent_reviews=recent_reviews,
                           reviews_total=review_count, users_total=user_count)
def import_index():
    table = {'id': 'project', 'header': [_('project'), _('entities'), _('description')], 'data': []}
    for project in ImportMapper.get_all_projects():
        table['data'].append([
            link(project),
            format_number(project.count),
            truncate_string(project.description)])
    return render_template('import/index.html', table=table)
Exemple #20
0
def index():
    # Popular reviews
    popular_reviews = Review.get_popular(6)
    for review in popular_reviews:
        # Preparing text for preview
        preview = markdown(review['text'], safe_mode="escape")
        review['preview'] = ''.join(BeautifulSoup(preview, "html.parser").findAll(text=True))

    # Recent reviews
    recent_reviews, _ = Review.list(sort='created', limit=9)

    # Statistics
    review_count = format_number(Review.get_count(is_draft = False))
    user_count = format_number(User.get_count())

    return render_template('index/index.html', popular_reviews=popular_reviews, recent_reviews=recent_reviews,
                           reviews_total=review_count, users_total=user_count)
Exemple #21
0
def hierarchy_update(id_: int) -> Union[str, Response]:
    hierarchy = g.types[id_]
    if hierarchy.category in ('standard', 'system'):
        abort(403)
    form = build_form('hierarchy', hierarchy)
    form.classes.choices = Type.get_class_choices(hierarchy)
    linked_entities = set()
    has_multiple_links = False
    for entity in get_entities_linked_to_type_recursive(id_, []):
        if entity.id in linked_entities:
            has_multiple_links = True
            break
        linked_entities.add(entity.id)
    if hasattr(form, 'multiple') and has_multiple_links:
        form.multiple.render_kw = {'disabled': 'disabled'}
    if form.validate_on_submit():
        if form.name.data != hierarchy.name and Type.get_types(form.name.data):
            flash(_('error name exists'), 'error')
        else:
            Transaction.begin()
            try:
                Type.update_hierarchy(hierarchy,
                                      sanitize(form.name.data),
                                      form.classes.data,
                                      multiple=(hierarchy.category == 'value'
                                                or (hasattr(form, 'multiple')
                                                    and form.multiple.data)
                                                or has_multiple_links))
                hierarchy.update(process_form_data(form, hierarchy))
                Transaction.commit()
            except Exception as e:  # pragma: no cover
                Transaction.rollback()
                logger.log('error', 'database', 'transaction failed', e)
                flash(_('error transaction'), 'error')
                abort(418)
            flash(_('info update'), 'info')
        tab = 'value' if g.types[id_].category == 'value' else 'custom'
        return redirect(
            f"{url_for('type_index')}#menu-tab-{tab}_collapse-{hierarchy.id}")
    form.multiple = hierarchy.multiple
    table = Table(paging=False)
    for class_name in hierarchy.classes:
        count = Type.get_form_count(hierarchy, class_name)
        table.rows.append([
            g.classes[class_name].label,
            format_number(count) if count else link(
                _('remove'),
                url_for(
                    'remove_class', id_=hierarchy.id, class_name=class_name))
        ])
    return render_template('display_form.html',
                           form=form,
                           table=table,
                           manual_page='entity/type',
                           title=_('types'),
                           crumbs=[[_('types'),
                                    url_for('type_index')], hierarchy,
                                   _('edit')])
Exemple #22
0
def import_index() -> str:
    table = Table([_('project'), _('entities'), _('description')])
    for project in ImportMapper.get_all_projects():
        table.rows.append([
            link(project),
            format_number(project.count),
            truncate_string(project.description)
        ])
    return render_template('import/index.html', table=table)
def index():
    # Popular reviews
    popular_reviews = Review.get_popular(6)
    for review in popular_reviews:
        # Preparing text for preview
        preview = markdown(review['text'], safe_mode="escape")
        review['preview'] = ''.join(BeautifulSoup(preview).findAll(text=True))

    # Recent reviews
    recent_reviews, _ = Review.list(sort='created', limit=9)

    # Statistics
    # TODO(roman): Move these into models:
    review_count = format_number(Review.query.filter(Review.is_draft == False).count())
    user_count = format_number(User.query.count())

    return render_template('index.html', popular_reviews=popular_reviews, recent_reviews=recent_reviews,
                           reviews_total=review_count, users_total=user_count)
Exemple #24
0
def walk_tree(param):
    text = ''
    for id_ in param if isinstance(param, list) else [param]:
        item = g.nodes[id_]
        count_subs = ' (' + format_number(
            item.count_subs) + ')' if item.count_subs else ''
        text += "{href: '" + url_for('node_view', id_=item.id) + "',"
        text += "text: '" + item.name.replace("'", "&apos;") + " "
        text += '<span style="font-weight:normal">' + format_number(
            item.count) + count_subs
        text += "', 'id':'" + str(item.id) + "'"
        if item.subs:
            text += ",'children' : ["
            for sub in item.subs:
                text += walk_tree(sub)
            text += "]"
        text += "},"
    return text
Exemple #25
0
    def test_basics(self):
        app = flask.Flask(__name__)
        babel.Babel(app)
        n = 1099

        with app.test_request_context():
            assert babel.format_number(n) == u'1,099'
            assert babel.format_decimal(Decimal('1010.99')) == u'1,010.99'
            assert babel.format_currency(n, 'USD') == '$1,099.00'
            assert babel.format_percent(0.19) == '19%'
            assert babel.format_scientific(10000) == u'1E4'
Exemple #26
0
    def test_basics(self):
        app = flask.Flask(__name__)
        b = babel.Babel(app)
        n = 1099

        with app.test_request_context():
            assert babel.format_number(n) == u'1,099'
            assert babel.format_decimal(Decimal('1010.99')) == u'1,010.99'
            assert babel.format_currency(n, 'USD') == '$1,099.00'
            assert babel.format_percent(0.19) == '19%'
            assert babel.format_scientific(10000) == u'1E4'
Exemple #27
0
def walk_tree(nodes: List[int]) -> List[Dict[str, Any]]:
    items = []
    for id_ in nodes:
        item = g.nodes[id_]
        count_subs = ' (' + format_number(
            item.count_subs) + ')' if item.count_subs else ''
        items.append({
            'id':
            item.id,
            'href':
            url_for('entity_view', id_=item.id),
            'a_attr': {
                'href': url_for('entity_view', id_=item.id)
            },
            'text':
            item.name.replace("'", "&apos;") + ' ' +
            format_number(item.count) + count_subs,
            'children':
            walk_tree(item.subs)
        })
    return items
Exemple #28
0
def get_provincial_breakdown(region):
    """Return provincial breakdown from DB"""
    b = {}
    doc = prov_bdown_coll.find_one({REGION_KEY: region}, {"_id": False})
    if doc:
        b = doc["breakdowns"]
        for key in b.keys():
            b[key] = sorted(b[key], key=lambda x: x['count'], reverse=True)
            areas_breakdown = b[key]
            for ab in areas_breakdown:
                ab['count'] = format_number(ab['count'])
    return b
Exemple #29
0
def walk_tree(param: Union[int, list]) -> str:
    """ Builds JSON for jsTree"""
    text = ''
    for id_ in param if type(param) is list else [param]:
        item = g.nodes[id_]
        count_subs = ' (' + format_number(
            item.count_subs) + ')' if item.count_subs else ''
        text += "{href: '" + url_for('node_view', id_=item.id) + "',"
        text += "a_attr: { href: '" + url_for('node_view',
                                              id_=item.id) + "'}, "
        text += "text: '" + item.name.replace("'", "&apos;") + " "
        text += '<span style="font-weight:normal">' + format_number(
            item.count) + count_subs
        text += "', 'id':'" + str(item.id) + "'"
        if item.subs:
            text += ",'children' : ["
            for sub in item.subs:
                text += walk_tree(sub)
            text += "]"
        text += "},"
    return text
Exemple #30
0
def import_index() -> str:
    table = Table([_('project'), _('entities'), _('description')])
    for project in Import.get_all_projects():
        table.rows.append(
            [link(project),
             format_number(project.count), project.description])
    return render_template(
        'import/index.html',
        table=table,
        title=_('import'),
        crumbs=[[_('admin'), f"{url_for('admin_index')}#tab-data"],
                _('import')])
Exemple #31
0
def get_regional_breakdown():
    """Return regional breakdown from DB"""
    doc = reg_bdown_coll.find_one({}, {"_id": False})
    if doc:
        breakdown = {
            key: sorted(doc[key], key=lambda x: x['count'], reverse=True)
            for key in doc
        }
        for key in doc:
            areas_breakdown = doc[key]
            for ab in areas_breakdown:
                ab['count'] = format_number(ab['count'])
    else:
        breakdown = {"err": "No data"}
    return breakdown
Exemple #32
0
def national_vax_view():
    """Render the vax report"""
    dashboard_title = gettext("Italy")
    page_title = f'{PAGE_BASE_TITLE} | {gettext("Vaccines")}'
    population = get_area_population('Italia')
    perc_pop_vax = get_perc_pop_vax(population)
    report_data = enrich_frontend_data(page_title=page_title,
                                       view_type=VIEW_TYPE,
                                       dashboard_title=dashboard_title,
                                       ts=int(time.time()),
                                       latest_update=get_latest_vax_update(),
                                       admins_perc=get_admins_perc(),
                                       perc_pop_vax=perc_pop_vax,
                                       trends=get_vax_trends(),
                                       population=format_number(population))
    return render_template("vaccines.html", **report_data)
Exemple #33
0
def user_index():
    tables = {'user': {
        'id': 'user',
        'header': ['username', 'group', 'email', 'newsletter', 'created', 'last login', 'entities'],
        'data': []}}
    for user in UserMapper.get_all():
        count = UserMapper.get_created_entities_count(user.id)
        tables['user']['data'].append([
            link(user),
            user.group,
            user.email if is_authorized('manager') or user.settings['show_email'] else '',
            _('yes') if user.settings['newsletter'] else '',
            format_date(user.created),
            format_date(user.login_last_success),
            format_number(count) if count else ''])
    return render_template('user/index.html', tables=tables)
Exemple #34
0
def regional_vax_view(region):
    """Render the vax regional view"""
    dashboard_title = region
    page_title = f'{PAGE_BASE_TITLE} | {gettext("Vaccines")} | {region}'
    area = PC_TO_OD_MAP[region]
    population = get_area_population(region)
    perc_pop_vax = get_perc_pop_vax(population, area)
    report_data = enrich_frontend_data(page_title=page_title,
                                       view_type=VIEW_TYPE,
                                       dashboard_title=dashboard_title,
                                       ts=int(time.time()),
                                       latest_update=get_latest_vax_update(),
                                       admins_perc=get_admins_perc(area=area),
                                       perc_pop_vax=perc_pop_vax,
                                       areas_length=len(REGIONS),
                                       area=region,
                                       trends=get_vax_trends(area),
                                       population=format_number(population))
    return render_template("vaccines.html", **report_data)
Exemple #35
0
def tab_header(id_: str,
               table: Optional[Table] = None,
               active: Optional[bool] = False) -> str:
    label = uc_first(_(id_.replace('_', ' ').replace('-', ' ').lower()))
    label += ' <span class="tab-counter">{counter}</span>'.format(
        counter=format_number(len(table.rows))) if table and len(
            table.rows) else ''
    return '''
        <li class="nav-item">
            <a 
                class="nav-link {active}" 
                data-toggle="tab" 
                role="tab" 
                aria-selected="{selected}" 
                href="#tab-{id}">{label}
            </a>
        </li>'''.format(active=' active' if active else '',
                        selected='true' if active else 'false',
                        label=label,
                        id=id_.replace('_', '-').replace(' ', '-'))
Exemple #36
0
def node_view(id_: int) -> str:
    from openatlas.models.link import LinkMapper
    node = g.nodes[id_]
    root = g.nodes[node.root[-1]] if node.root else None
    super_ = g.nodes[node.root[0]] if node.root else None
    header = [_('name'), _('class'), _('info')]
    if root and root.value_type:  # pragma: no cover
        header = [_('name'), _('value'), _('class'), _('info')]
    tables = {'info': get_entity_data(node), 'entities': Table(header)}
    for entity in node.get_linked_entities(['P2', 'P89'],
                                           inverse=True,
                                           nodes=True):
        # If it is a place location get the corresponding object
        entity = entity if node.class_.code == 'E55' else entity.get_linked_entity(
            'P53', True)
        if entity:  # If not entity it is a place node, so do not add
            data = [link(entity)]
            if root and root.value_type:  # pragma: no cover
                data.append(format_number(entity.nodes[node]))
            data.append(g.classes[entity.class_.code].name)
            data.append(truncate_string(entity.description))
            tables['entities'].rows.append(data)
    tables['link_entities'] = Table([_('domain'), _('range')])
    for row in LinkMapper.get_entities_by_node(node):
        tables['link_entities'].rows.append([
            link(EntityMapper.get_by_id(row.domain_id)),
            link(EntityMapper.get_by_id(row.range_id))
        ])
    tables['subs'] = Table([_('name'), _('count'), _('info')])
    for sub_id in node.subs:
        sub = g.nodes[sub_id]
        tables['subs'].rows.append(
            [link(sub), sub.count,
             truncate_string(sub.description)])
    return render_template('types/view.html',
                           node=node,
                           super_=super_,
                           tables=tables,
                           root=root)
def get_entity_data(entity, location=None):
    """
    Return related entity information for a table for view.
    The location parameter is for places which have a location attached.
    """
    data = []
    type_data = OrderedDict()

    # Nodes
    if location:
        entity.nodes.update(location.nodes)  # Add location types
    for node, node_value in entity.nodes.items():
        root = g.nodes[node.root[-1]]
        name = 'type' if root.name in app.config['BASE_TYPES'] else root.name
        if root.name not in type_data:
            type_data[name] = []
        html = link(node) + (': ' + format_number(node_value) if root.value_type else '')
        type_data[name].append(html)

    # Sort by name
    type_data = OrderedDict(sorted(type_data.items(), key=lambda t: t[0]))
    for root_type in type_data:
        type_data[root_type].sort()

    # Move the base type to the top
    if 'type' in type_data:
        type_data.move_to_end('type', last=False)
    for root_name, nodes in type_data.items():
        data.append((root_name, '<br />'.join(nodes)))

    # Info for places
    if entity.class_.code in app.config['CLASS_CODES']['place']:
        aliases = entity.get_linked_entities('P1')
        if aliases:
            data.append((uc_first(_('alias')), '<br />'.join([x.name for x in aliases])))

    # Info for files
    if entity.system_type == 'file':
        data.append((uc_first(_('size')), print_file_size(entity)))
        data.append((uc_first(_('extension')), print_file_extension(entity)))

    # Info for events
    if entity.class_.code in app.config['CLASS_CODES']['event']:
        super_event = entity.get_linked_entity('P117')
        if super_event:
            data.append((uc_first(_('sub event of')), link(super_event)))
        place = entity.get_linked_entity('P7')
        if place:
            data.append((uc_first(_('location')), link(place.get_linked_entity('P53', True))))
        # Info for acquisitions
        if entity.class_.code == 'E8':
            data.append((uc_first(_('recipient')), '<br />'.join(
                [link(recipient) for recipient in entity.get_linked_entities('P22')])))
            data.append((uc_first(_('donor')), '<br />'.join(
                [link(donor) for donor in entity.get_linked_entities('P23')])))
            data.append((uc_first(_('given place')), '<br />'.join(
                [link(place) for place in entity.get_linked_entities('P24')])))

    # Info for actors
    if entity.class_.code in app.config['CLASS_CODES']['actor']:
        aliases = entity.get_linked_entities('P131')
        if aliases:
            data.append((uc_first(_('alias')), '<br />'.join([x.name for x in aliases])))

    # Dates
    date_types = OrderedDict([('OA1', _('first')), ('OA3', _('birth')), ('OA2', _('last')),
                              ('OA4', _('death')), ('OA5', _('begin')), ('OA6', _('end'))])
    for code, label in date_types.items():
        if code in entity.dates:
            if 'exact date value' in entity.dates[code]:
                html = format_date(entity.dates[code]['exact date value']['date'])
                html += ' ' + entity.dates[code]['exact date value']['info']
                data.append((uc_first(label), html))
            else:
                html = uc_first(_('between')) + ' '
                html += format_date(entity.dates[code]['from date value']['date'])
                html += ' and ' + format_date(entity.dates[code]['to date value']['date'])
                html += ' ' + entity.dates[code]['from date value']['info']
                data.append((uc_first(label), html))

    # Additional info for advanced layout
    if hasattr(current_user, 'settings') and current_user.settings['layout'] == 'advanced':
        data.append((uc_first(_('class')), link(entity.class_)))
        info = openatlas.logger.get_log_for_advanced_view(entity.id)
        data.append((_('created'), format_date(entity.created) + ' ' + link(info['creator'])))
        if info['modified']:
            html = format_date(info['modified']) + ' ' + link(info['modifier'])
            data.append((_('modified'), html))
        if info['import_project']:
            data.append((_('imported from'), link(info['import_project'])))
        if info['import_user']:
            data.append((_('imported by'), link(info['import_user'])))
        if info['import_origin_id']:
            data.append(('origin ID', info['import_origin_id']))

    return data
Exemple #38
0
def admin_index(action: Optional[str] = None,
                id_: Optional[int] = None) -> Union[str, Response]:
    if is_authorized('manager'):
        if id_ and action == 'delete_user':
            user = User.get_by_id(id_)
            if not user \
                    or user.id == current_user.id \
                    or (user.group == 'admin' and not is_authorized('admin')):
                abort(403)
            User.delete(id_)
            flash(_('user deleted'), 'info')
        elif action == 'remove_logo':
            Settings.set_logo()
            return redirect(f"{url_for('admin_index')}#tab-file")
    tables = {
        'user':
        Table([
            'username', 'name', 'group', 'email', 'newsletter', 'created',
            'last login', 'entities'
        ],
              defs=[{
                  'className': 'dt-body-right',
                  'targets': 7
              }]),
        'content':
        Table(['name'] + list(app.config['LANGUAGES']))
    }
    for user in User.get_all():
        count = User.get_created_entities_count(user.id)
        email = user.email \
            if is_authorized('manager') or user.settings['show_email'] else ''
        tables['user'].rows.append([
            link(user), user.real_name, user.group, email,
            _('yes') if user.settings['newsletter'] else '',
            format_date(user.created),
            format_date(user.login_last_success),
            format_number(count) if count else ''
        ])
    for item, languages in get_content().items():
        content = [uc_first(_(item))]
        for language in app.config['LANGUAGES']:
            content.append(sanitize(languages[language], 'text'))
        content.append(link(_('edit'), url_for('admin_content', item=item)))
        tables['content'].rows.append(content)
    form = None
    if is_authorized('admin'):
        form = TestMailForm()
        if form.validate_on_submit(
        ) and g.settings['mail']:  # pragma: no cover
            subject = _('Test mail from %(site_name)s',
                        site_name=g.settings['site_name'])
            body = _('This test mail was sent by %(username)s',
                     username=current_user.username)
            body += f" {_('at')} '{request.headers['Host']}"
            if send_mail(subject, body, form.receiver.data):
                flash(
                    _('A test mail was sent to %(email)s.',
                      email=form.receiver.data), 'info')
        else:
            form.receiver.data = current_user.email
    tabs = {
        'files':
        Tab(_('files'),
            buttons=[
                manual('entity/file'),
                button(_('edit'), url_for('admin_settings', category='files'))
                if is_authorized('manager') else '',
                button(_('list'), url_for('index', view='file')),
                button(_('file'), url_for('insert', class_='file'))
            ],
            content=render_template('admin/file.html',
                                    info=get_form_settings(FilesForm()),
                                    disk_space_info=get_disk_space_info())),
        'user':
        Tab(_('user'),
            table=tables['user'],
            buttons=[
                manual('admin/user'),
                button(_('activity'), url_for('user_activity')),
                button(_('newsletter'), url_for('admin_newsletter'))
                if is_authorized('manager') and g.settings['mail'] else '',
                button(_('user'), url_for('user_insert'))
                if is_authorized('manager') else ''
            ])
    }
    if is_authorized('admin'):
        tabs['general'] = Tab(
            'general',
            content=display_info(get_form_settings(GeneralForm())),
            buttons=[
                manual('admin/general'),
                button(_('edit'), url_for('admin_settings',
                                          category='general')),
                button(_('system log'), url_for('admin_log'))
            ])
        tabs['email'] = Tab(
            'email',
            content=display_info(get_form_settings(MailForm())),
            buttons=[
                manual('admin/mail'),
                button(_('edit'), url_for('admin_settings', category='mail'))
            ])
        if g.settings['mail']:
            tabs['email'].content += display_form(form)
    if is_authorized('manager'):
        tabs['modules'] = Tab(_('modules'),
                              content=f"""
                <h1>{_('Defaults for new user')}</h1>
                {display_info(get_form_settings(ModulesForm()))}""",
                              buttons=[
                                  manual('admin/modules'),
                                  button(
                                      _('edit'),
                                      url_for('admin_settings',
                                              category='modules'))
                              ])
        tabs['map'] = Tab('map',
                          content=display_info(get_form_settings(MapForm())),
                          buttons=[
                              manual('admin/map'),
                              button(_('edit'),
                                     url_for('admin_settings', category='map'))
                          ])
        tabs['content'] = Tab('content',
                              content=tables['content'].display(),
                              buttons=[manual('admin/content')])
    if is_authorized('contributor'):
        tabs['data'] = Tab('data',
                           content=render_template(
                               'admin/data.html',
                               imports=Import.get_all_projects(),
                               info=get_form_settings(ApiForm())))
    return render_template('tabs.html',
                           tabs=tabs,
                           title=_('admin'),
                           crumbs=[_('admin')])
Exemple #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)