Ejemplo n.º 1
0
 def search(term, codes, description=False, own=False):
     sql = EntityMapper.sql
     if own:
         sql += " LEFT JOIN web.user_log ul ON e.id = ul.entity_id "
     sql += " WHERE LOWER(e.name) LIKE LOWER(%(term)s)"
     sql += " OR lower(e.description) LIKE lower(%(term)s) AND " if description else " AND "
     sql += " ul.user_id = %(user_id)s AND " if own else ''
     sql += " e.class_code IN %(codes)s"
     sql += " GROUP BY e.id ORDER BY e.name"
     g.cursor.execute(
         sql, {
             'term': '%' + term + '%',
             'codes': tuple(codes),
             'user_id': current_user.id
         })
     debug_model['div sql'] += 1
     entities = []
     for row in g.cursor.fetchall():
         if row.class_code == 'E82':  # If found in actor alias
             entities.append(
                 LinkMapper.get_linked_entity(row.id, 'P131', True))
         elif row.class_code == 'E41':  # If found in place alias
             entities.append(
                 LinkMapper.get_linked_entity(row.id, 'P1', True))
         else:
             entities.append(Entity(row))
     return entities
Ejemplo n.º 2
0
def relation_update(id_: int, origin_id: int) -> str:
    link_ = LinkMapper.get_by_id(id_)
    domain = EntityMapper.get_by_id(link_.domain.id)
    range_ = EntityMapper.get_by_id(link_.range.id)
    origin = range_ if origin_id == range_.id else domain
    related = range_ if origin_id == domain.id else domain
    form = build_form(RelationForm, 'Actor Actor Relation', link_, request)
    del form.actor, form.insert_and_continue, form.origin_id
    if form.validate_on_submit():
        g.cursor.execute('BEGIN')
        try:
            link_.delete()
            if form.inverse.data:
                link_ = LinkMapper.get_by_id(related.link('OA7', origin, form.description.data))
            else:
                link_ = LinkMapper.get_by_id(origin.link('OA7', related, form.description.data))
            link_.set_dates(form)
            link_.type = get_link_type(form)
            link_.update()
            g.cursor.execute('COMMIT')
            flash(_('info update'), 'info')
        except Exception as e:  # pragma: no cover
            g.cursor.execute('ROLLBACK')
            logger.log('error', 'database', 'transaction failed', e)
            flash(_('error transaction'), 'error')
        return redirect(url_for('actor_view', id_=origin.id) + '#tab-relation')
    if origin.id == range_.id:
        form.inverse.data = True
    form.save.label.text = _('save')
    form.populate_dates(link_)
    return render_template('relation/update.html', origin=origin, form=form, related=related)
Ejemplo n.º 3
0
def relation_insert(origin_id: int) -> str:
    origin = EntityMapper.get_by_id(origin_id)
    form = build_form(RelationForm, 'Actor Actor Relation')
    form.origin_id.data = origin.id
    if form.validate_on_submit():
        g.cursor.execute('BEGIN')
        try:
            for actor in EntityMapper.get_by_ids(ast.literal_eval(form.actor.data)):
                if form.inverse.data:
                    link_ = LinkMapper.get_by_id(actor.link('OA7', origin, form.description.data))
                else:
                    link_ = LinkMapper.get_by_id(origin.link('OA7', actor, form.description.data))
                link_.set_dates(form)
                link_.type = get_link_type(form)
                link_.update()
            g.cursor.execute('COMMIT')
            flash(_('entity created'), 'info')
        except Exception as e:  # pragma: no cover
            g.cursor.execute('ROLLBACK')
            logger.log('error', 'database', 'transaction failed', e)
            flash(_('error transaction'), 'error')
        if form.continue_.data == 'yes':
            return redirect(url_for('relation_insert', origin_id=origin_id))
        return redirect(url_for('actor_view', id_=origin.id) + '#tab-relation')
    return render_template('relation/insert.html', origin=origin, form=form)
Ejemplo n.º 4
0
def admin_check_link_duplicates(delete: Optional[str] = None) -> str:
    if delete:
        delete_count = str(LinkMapper.delete_link_duplicates())
        logger.log('info', 'admin', 'Deleted duplicate links: ' + delete_count)
        flash(_('deleted links') + ': ' + delete_count, 'info')
        return redirect(url_for('admin_check_link_duplicates'))
    table = Table(['domain', 'range', 'property_code', 'description', 'type_id', 'begin_from',
                   'begin_to', 'begin_comment', 'end_from', 'end_to', 'end_comment', 'count'])

    for result in LinkMapper.check_link_duplicates():
        table.rows.append([link(EntityMapper.get_by_id(result.domain_id)),
                           link(EntityMapper.get_by_id(result.range_id)),
                           link(g.properties[result.property_code]),
                           truncate_string(result.description),
                           link(g.nodes[result.type_id]) if result.type_id else '',
                           format_date(result.begin_from),
                           format_date(result.begin_to),
                           truncate_string(result.begin_comment),
                           format_date(result.end_from),
                           format_date(result.end_to),
                           truncate_string(result.end_comment),
                           result.count])
    duplicates = False
    if table.rows:
        duplicates = True
    else:  # If no exact duplicates where found check if single types are used multiple times
        table = Table(['entity', 'class', 'base type', 'incorrect multiple types'],
                      rows=LinkMapper.check_single_type_duplicates())
    return render_template('admin/check_link_duplicates.html', table=table, duplicates=duplicates)
Ejemplo n.º 5
0
def member_update(id_: int, origin_id: int) -> str:
    link_ = LinkMapper.get_by_id(id_)
    domain = EntityMapper.get_by_id(link_.domain.id)
    range_ = EntityMapper.get_by_id(link_.range.id)
    origin = range_ if origin_id == range_.id else domain
    form = build_form(MemberForm, 'Member', link_, request)
    del form.actor, form.group, form.insert_and_continue
    if form.validate_on_submit():
        g.cursor.execute('BEGIN')
        try:
            link_.delete()
            link_ = LinkMapper.get_by_id(
                domain.link('P107', range_, form.description.data))
            link_.set_dates(form)
            link_.type = get_link_type(form)
            link_.update()
            g.cursor.execute('COMMIT')
        except Exception as e:  # pragma: no cover
            g.cursor.execute('ROLLBACK')
            logger.log('error', 'database', 'transaction failed', e)
            flash(_('error transaction'), 'error')
        tab = '#tab-member-of' if origin.id == range_.id else '#tab-member'
        return redirect(url_for('actor_view', id_=origin.id) + tab)
    form.save.label.text = _('save')
    form.populate_dates(link_)
    related = range_ if origin_id == domain.id else domain
    return render_template('member/update.html',
                           origin=origin,
                           form=form,
                           related=related)
Ejemplo n.º 6
0
def save(form, event=None, code=None, origin=None):
    g.cursor.execute('BEGIN')
    try:
        if event:
            log_action = 'update'
            LinkMapper.delete_by_codes(event, ['P117', 'P7', 'P24'])
        else:
            log_action = 'insert'
            event = EntityMapper.insert(code, form.name.data)
        event.name = form.name.data
        event.description = form.description.data
        event.update()
        event.save_dates(form)
        event.save_nodes(form)
        if form.event.data:
            event.link('P117', int(form.event.data))
        if form.place.data:
            place = LinkMapper.get_linked_entity(int(form.place.data), 'P53')
            event.link('P7', place)
        if event.class_.code == 'E8' and form.given_place.data:  # Link place for acquisition
            event.link('P24', ast.literal_eval(form.given_place.data))
        url = url_for('event_view', id_=event.id)
        if origin:
            view_name = get_view_name(origin)
            url = url_for(view_name + '_view', id_=origin.id) + '#tab-event'
            if view_name == 'reference':
                link_id = origin.link('P67', event)
                url = url_for('reference_link_update',
                              link_id=link_id,
                              origin_id=origin.id)
            elif view_name == 'source':
                origin.link('P67', event)
            elif view_name == 'actor':
                link_id = event.link('P11', origin)
                url = url_for('involvement_update',
                              id_=link_id,
                              origin_id=origin.id)
            elif view_name == 'file':
                origin.link('P67', event)
        if form.continue_.data == 'yes':
            url = url_for('event_insert',
                          code=code,
                          origin_id=origin.id if origin else None)
        g.cursor.execute('COMMIT')
        logger.log_user(event.id, log_action)
        flash(
            _('entity created')
            if log_action == 'insert' else _('info update'), 'info')
    except Exception as e:  # pragma: no cover
        g.cursor.execute('ROLLBACK')
        logger.log('error', 'database', 'transaction failed', e)
        flash(_('error transaction'), 'error')
        url = url_for('event_index')
    return url
Ejemplo n.º 7
0
    def get_invalid_link_dates():
        """ Search for links with invalid date combinations, e.g. begin after end"""
        sql = """
        SELECT l.id FROM model.link l

        LEFT JOIN model.link_property bl1 ON l.id = bl1.domain_id
            AND bl1.property_code IN ('OA1', 'OA3', 'OA5')
        LEFT JOIN model.entity b1 ON bl1.range_id = b1.id
            AND b1.system_type IN ('from date value', 'exact date value')

        LEFT JOIN model.link_property bl2 ON l.id = bl2.domain_id
            AND bl2.property_code IN ('OA1', 'OA3', 'OA5')
        LEFT JOIN model.entity b2 ON bl2.range_id = b2.id AND b2.system_type = 'to date value'

        LEFT JOIN model.link_property el1 ON l.id = el1.domain_id
            AND el1.property_code IN ('OA2', 'OA4', 'OA6')
        LEFT JOIN model.entity e1 ON el1.range_id = e1.id
            AND e1.system_type IN ('from date value', 'exact date value')

        LEFT JOIN model.link_property el2 ON l.id = el2.domain_id
            AND el2.property_code IN ('OA2', 'OA4', 'OA6')
        LEFT JOIN model.entity e2 ON el2.range_id = e2.id AND e2.system_type = 'to date value'

        GROUP BY l.id
        HAVING l.property_code IN ('OA7', 'P107', 'P11', 'P14', 'P22', 'P23')
                AND (max(b1.value_timestamp) > max(b2.value_timestamp)
                OR max(e1.value_timestamp) > max(e2.value_timestamp)
                OR (max(b1.value_timestamp) IS NOT NULL AND max(e1.value_timestamp) IS NOT NULL
                    AND max(b1.value_timestamp) > max(e1.value_timestamp))
                OR (max(b2.value_timestamp) IS NOT NULL AND max(e2.value_timestamp) IS NOT NULL
                    AND max(b2.value_timestamp) > max(e2.value_timestamp)));"""
        g.cursor.execute(sql)
        debug_model['div sql'] += 1
        return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
Ejemplo n.º 8
0
def admin_check_links(check: Optional[str] = None) -> str:
    table = None
    if check:
        table = Table(['domain', 'property', 'range'])
        for result in LinkMapper.check_links():  # pragma: no cover
            table.rows.append([result['domain'], result['property'], result['range']])
    return render_template('admin/check_links.html', table=table, check=check)
Ejemplo n.º 9
0
def member_update(id_, origin_id):
    link_ = LinkMapper.get_by_id(id_)
    domain = EntityMapper.get_by_id(link_.domain.id)
    range_ = EntityMapper.get_by_id(link_.range.id)
    origin = range_ if origin_id == range_.id else domain
    form = build_form(MemberForm, 'Member', link_, request)
    del form.actor, form.group, form.insert_and_continue
    if form.validate_on_submit():
        g.cursor.execute('BEGIN')
        try:
            link_.delete()
            link_id = domain.link('P107', range_, form.description.data)
            DateMapper.save_link_dates(link_id, form)
            NodeMapper.save_link_nodes(link_id, form)
            g.cursor.execute('COMMIT')
        except Exception as e:  # pragma: no cover
            g.cursor.execute('ROLLBACK')
            logger.log('error', 'database', 'transaction failed', e)
            flash(_('error transaction'), 'error')
        tab = '#tab-member-of' if origin.id == range_.id else '#tab-member'
        return redirect(url_for('actor_view', id_=origin.id) + tab)
    form.save.label.text = _('save')
    link_.set_dates()
    form.populate_dates(link_)
    related = range_ if origin_id == domain.id else domain
    return render_template('member/update.html', origin=origin, form=form, related=related)
Ejemplo n.º 10
0
def relation_update(id_, origin_id):
    link_ = LinkMapper.get_by_id(id_)
    domain = EntityMapper.get_by_id(link_.domain.id)
    range_ = EntityMapper.get_by_id(link_.range.id)
    origin = range_ if origin_id == range_.id else domain
    related = range_ if origin_id == domain.id else domain
    form = build_form(RelationForm, 'Actor Actor Relation', link_, request)
    del form.actor, form.insert_and_continue, form.origin_id
    if form.validate_on_submit():
        g.cursor.execute('BEGIN')
        try:
            link_.delete()
            if form.inverse.data:
                link_id = related.link('OA7', origin, form.description.data)
            else:
                link_id = origin.link('OA7', related, form.description.data)
            DateMapper.save_link_dates(link_id, form)
            NodeMapper.save_link_nodes(link_id, form)
            g.cursor.execute('COMMIT')
            flash(_('info update'), 'info')
        except Exception as e:  # pragma: no cover
            g.cursor.execute('ROLLBACK')
            logger.log('error', 'database', 'transaction failed', e)
            flash(_('error transaction'), 'error')
        return redirect(url_for('actor_view', id_=origin.id) + '#tab-relation')
    if origin.id == range_.id:
        form.inverse.data = True
    form.save.label.text = _('save')
    link_.set_dates()
    form.populate_dates(link_)
    return render_template('relation/update.html', origin=origin, form=form, related=related)
Ejemplo n.º 11
0
def source_add(origin_id):
    """ Link an entity to source coming from the entity."""
    origin = EntityMapper.get_by_id(origin_id)
    if request.method == 'POST':
        g.cursor.execute('BEGIN')
        try:
            for value in request.form.getlist('values'):
                LinkMapper.insert(int(value), 'P67', origin.id)
            g.cursor.execute('COMMIT')
        except Exception as e:  # pragma: no cover
            g.cursor.execute('ROLLBACK')
            logger.log('error', 'database', 'transaction failed', e)
            flash(_('error transaction'), 'error')
        return redirect(url_for(get_view_name(origin) + '_view', id_=origin.id) + '#tab-source')
    form = build_table_form('source', origin.get_linked_entities('P67', True))
    return render_template('source/add.html', origin=origin, form=form)
def involvement_update(id_, origin_id):
    link_ = LinkMapper.get_by_id(id_)
    event = EntityMapper.get_by_id(link_.domain.id)
    actor = EntityMapper.get_by_id(link_.range.id)
    origin = event if origin_id == event.id else actor
    form = build_form(ActorForm, 'Involvement', link_, request)
    form.save.label.text = _('save')
    del form.actor, form.event, form.insert_and_continue
    form.activity.choices = [('P11', g.properties['P11'].name)]
    if event.class_.code in ['E7', 'E8', 'E12']:
        form.activity.choices.append(('P14', g.properties['P14'].name))
    if event.class_.code == 'E8':
        form.activity.choices.append(('P22', g.properties['P22'].name))
        form.activity.choices.append(('P23', g.properties['P23'].name))
    if form.validate_on_submit():
        g.cursor.execute('BEGIN')
        try:
            link_.delete()
            link_id = event.link(form.activity.data, actor, form.description.data)
            DateMapper.save_link_dates(link_id, form)
            NodeMapper.save_link_nodes(link_id, form)
            g.cursor.execute('COMMIT')
        except Exception as e:  # pragma: no cover
            g.cursor.execute('ROLLBACK')
            logger.log('error', 'database', 'transaction failed', e)
            flash(_('error transaction'), 'error')
        tab = 'actor' if origin.view_name == 'event' else 'event'
        return redirect(url_for(origin.view_name + '_view', id_=origin.id) + '#tab-' + tab)
    form.activity.data = link_.property.code
    form.description.data = link_.description
    link_.set_dates()
    form.populate_dates(link_)
    return render_template('involvement/update.html', origin=origin, form=form,
                           linked_object=event if origin_id != event.id else actor)
Ejemplo n.º 13
0
def build_move_form(form, node) -> Form:
    root = g.nodes[node.root[-1]]
    setattr(form, str(root.id), TreeField(str(root.id)))
    form_instance = form(obj=node)

    # Delete custom fields except the ones specified for the form
    delete_list = []  # Can't delete fields in the loop so creating a list for later deletion
    for field in form_instance:
        if type(field) is TreeField and int(field.id) != root.id:
            delete_list.append(field.id)
    for item in delete_list:
        delattr(form_instance, item)
    choices = []
    if root.class_.code == 'E53':
        for entity in node.get_linked_entities('P89', True):
            place = entity.get_linked_entity('P53', True)
            if place:
                choices.append((entity.id, place.name))
    elif root.name in app.config['PROPERTY_TYPES']:
        for row in LinkMapper.get_entities_by_node(node):
            domain = EntityMapper.get_by_id(row.domain_id)
            range_ = EntityMapper.get_by_id(row.range_id)
            choices.append((row.id, domain.name + ' - ' + range_.name))
    else:
        for entity in node.get_linked_entities('P2', True):
            choices.append((entity.id, entity.name))

    form_instance.selection.choices = choices
    return form_instance
Ejemplo n.º 14
0
def build_move_form(form, node) -> Form:
    root = g.nodes[node.root[-1]]
    setattr(form, str(root.id), TreeField(str(root.id)))
    form_instance = form(obj=node)

    # Delete custom fields except the ones specified for the form
    delete_list = [
    ]  # Can't delete fields in the loop so creating a list for later deletion
    for field in form_instance:
        if type(field) is TreeField and int(field.id) != root.id:
            delete_list.append(field.id)
    for item in delete_list:
        delattr(form_instance, item)

    choices = []
    if root.class_.code == 'E53':
        for entity in node.get_linked_entities('P89', True):
            place = entity.get_linked_entity('P53', True)
            if place:
                choices.append((entity.id, place.name))
    elif root.name in app.config['PROPERTY_TYPES']:
        for row in LinkMapper.get_entities_by_node(node):
            domain = EntityMapper.get_by_id(row.domain_id)
            range_ = EntityMapper.get_by_id(row.range_id)
            choices.append((row.id, domain.name + ' - ' + range_.name))
    else:
        for entity in node.get_linked_entities('P2', True):
            choices.append((entity.id, entity.name))

    form_instance.selection.choices = choices
    return form_instance
Ejemplo n.º 15
0
    def test_model(self):
        with app.app_context():
            rv = self.app.get(url_for('model_index'))
            assert b'Browse' in rv.data
            rv = self.app.get(url_for('class_index'))
            assert b'E1' in rv.data
            rv = self.app.get(url_for('class_view', code='E4'))
            assert b'Domain for' in rv.data
            rv = self.app.get(url_for('property_index'))
            assert b'P1' in rv.data
            rv = self.app.get(url_for('property_view', code='P68'))
            assert b'P68' in rv.data
            data = {'domain': 'E1', 'range': 'E1', 'property': 'P13'}
            rv = self.app.post(url_for('model_index'), data=data)
            assert b'Wrong domain' in rv.data
            data = {'domain': 'E1', 'range': 'E1', 'property': 'P67'}
            rv = self.app.post(url_for('model_index'), data=data)
            assert b'Wrong domain' in rv.data

            self.login()
            with app.test_request_context(
            ):  # Insert data to display in network view
                app.preprocess_request()
                actor = EntityMapper.insert('E21', 'King Arthur')
                event = EntityMapper.insert('E7', 'Battle of Camlann')
                prop_object = EntityMapper.insert('E89',
                                                  'Propositional Object')
                LinkMapper.insert(actor, 'P11', event)
                LinkMapper.insert(actor, 'P67', prop_object)
            rv = self.app.get(url_for('model_network'))
            assert b'Orphans' in rv.data
            data = {
                'orphans': True,
                'width': 100,
                'height': 40,
                'distance': -666,
                'charge': 500
            }
            rv = self.app.post(url_for('model_network'), data=data)
            assert b'666' in rv.data

            # Translations
            self.app.get('/index/setlocale/de')
            rv = self.app.get(url_for('property_view', code='P68'))
            assert b'verweist auf' in rv.data
            rv = self.app.get(url_for('class_view', code='E4'))
            assert b'Phase' in rv.data
Ejemplo n.º 16
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)
Ejemplo n.º 17
0
 def link(self,
          code: str,
          range_,
          description: Optional[str] = None,
          inverse: Optional[bool] = False,
          type_id: Optional[int] = None) -> Union[int, None]:
     return LinkMapper.insert(self, code, range_, description, inverse,
                              type_id)
Ejemplo n.º 18
0
 def get_linked_entities(self,
                         code: str,
                         inverse: Optional[bool] = False,
                         nodes: Optional[bool] = False):
     return LinkMapper.get_linked_entities(self,
                                           code,
                                           inverse=inverse,
                                           nodes=nodes)
Ejemplo n.º 19
0
 def get_linked_entities(self,
                         code: Union[str, List[str]],
                         inverse: bool = False,
                         nodes: bool = False) -> List[Entity]:
     return LinkMapper.get_linked_entities(self.id,
                                           code,
                                           inverse=inverse,
                                           nodes=nodes)
Ejemplo n.º 20
0
def involvement_insert(origin_id: int) -> str:
    origin = EntityMapper.get_by_id(origin_id)
    form = build_form(ActorForm, 'Involvement')
    if origin.view_name == 'event':
        del form.event
    else:
        del form.actor
    form.activity.choices = [('P11', g.properties['P11'].name_inverse)]
    if origin.class_.code in ['E7', 'E8']:
        form.activity.choices.append(('P14', g.properties['P14'].name_inverse))
    if origin.class_.code == 'E8':
        form.activity.choices.append(('P22', g.properties['P22'].name_inverse))
        form.activity.choices.append(('P23', g.properties['P23'].name_inverse))
    if form.validate_on_submit():
        g.cursor.execute('BEGIN')
        try:
            if origin.view_name == 'event':
                for actor in EntityMapper.get_by_ids(
                        ast.literal_eval(form.actor.data)):
                    link_ = LinkMapper.get_by_id(
                        origin.link(form.activity.data, actor,
                                    form.description.data))
                    link_.set_dates(form)
                    link_.type = get_link_type(form)
                    link_.update()
            else:
                for event in EntityMapper.get_by_ids(
                        ast.literal_eval(form.event.data)):
                    link_ = LinkMapper.get_by_id(
                        event.link(form.activity.data, origin,
                                   form.description.data))
                    link_.set_dates(form)
                    link_.type = get_link_type(form)
                    link_.update()
            g.cursor.execute('COMMIT')
            flash(_('entity created'), 'info')
        except Exception as e:  # pragma: no cover
            g.cursor.execute('ROLLBACK')
            logger.log('error', 'database', 'transaction failed', e)
            flash(_('error transaction'), 'error')
        if form.continue_.data == 'yes':
            return redirect(url_for('involvement_insert', origin_id=origin_id))
        tab = 'actor' if origin.view_name == 'event' else 'event'
        return redirect(
            url_for(origin.view_name + '_view', id_=origin.id) + '#tab-' + tab)
    return render_template('involvement/insert.html', origin=origin, form=form)
Ejemplo n.º 21
0
 def link(self,
          code: str,
          range_: Union[Entity, List[Entity]],
          description: Optional[str] = None,
          inverse: bool = False,
          type_id: Optional[int] = None) -> List[int]:
     return LinkMapper.insert(self, code, range_, description, inverse,
                              type_id)
Ejemplo n.º 22
0
 def get_linked_entity(self,
                       code: str,
                       inverse: bool = False,
                       nodes: bool = False) -> Optional[Entity]:
     return LinkMapper.get_linked_entity(self.id,
                                         code,
                                         inverse=inverse,
                                         nodes=nodes)
Ejemplo n.º 23
0
    def test_member(self):
        with app.app_context():
            self.login()
            with app.test_request_context():
                app.preprocess_request()
                actor = EntityMapper.insert('E21', 'Ripley')
                group = EntityMapper.insert('E74', 'Space Marines')

            # Add membership
            rv = self.app.get(url_for('member_insert', origin_id=group.id))
            assert b'Actor Function' in rv.data
            data = {'group': str([group.id])}
            rv = self.app.post(url_for('membership_insert',
                                       origin_id=actor.id),
                               data=data,
                               follow_redirects=True)
            assert b'Space Marines' in rv.data
            data = {'group': str([group.id]), 'continue_': 'yes'}
            rv = self.app.post(url_for('membership_insert',
                                       origin_id=actor.id),
                               data=data,
                               follow_redirects=True)
            assert b'Space Marines' in rv.data

            rv = self.app.post(url_for('membership_insert',
                                       origin_id=group.id),
                               data=data,
                               follow_redirects=True)
            assert b"Can't link to itself" in rv.data
            rv = self.app.post(url_for('member_insert', origin_id=actor.id),
                               data={'actor': str([actor.id])},
                               follow_redirects=True)
            assert b"Can't link to itself" in rv.data

            # Add member to group
            data = {'actor': str([actor.id])}
            rv = self.app.post(url_for('member_insert', origin_id=group.id),
                               data=data,
                               follow_redirects=True)
            assert b'Ripley' in rv.data
            data['continue_'] = 'yes'
            rv = self.app.post(url_for('member_insert', origin_id=group.id),
                               data=data,
                               follow_redirects=True)
            assert b'Ripley' in rv.data

            # Update
            with app.test_request_context():
                app.preprocess_request()
                link_id = LinkMapper.get_links(group.id, 'P107')[0].id
            rv = self.app.get(
                url_for('member_update', id_=link_id, origin_id=group.id))
            assert b'Ripley' in rv.data
            rv = self.app.post(
                url_for('member_update', id_=link_id, origin_id=group.id),
                data={'description': 'We are here to help you.'},
                follow_redirects=True)
            assert b'here to help' in rv.data
Ejemplo n.º 24
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)
Ejemplo n.º 25
0
 def get_invalid_link_dates() -> list:
     """ Search for links with invalid date combinations, e.g. begin after end"""
     from openatlas.models.link import LinkMapper
     sql = """
         SELECT id FROM model.link WHERE
             begin_from > begin_to OR end_from > end_to
             OR (begin_from IS NOT NULL AND end_from IS NOT NULL AND begin_from > end_from)
             OR (begin_to IS NOT NULL AND end_to IS NOT NULL AND begin_to > end_to);"""
     g.execute(sql)
     return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
Ejemplo n.º 26
0
 def get_invalid_link_dates():
     """ Search for links with invalid date combinations, e.g. begin after end"""
     from openatlas.models.link import LinkMapper
     sql = """
         SELECT id FROM model.link WHERE
             begin_from > begin_to OR end_from > end_to
             OR (begin_from IS NOT NULL AND end_from IS NOT NULL AND begin_from > end_from)
             OR (begin_to IS NOT NULL AND end_to IS NOT NULL AND begin_to > end_to);"""
     g.cursor.execute(sql)
     debug_model['div sql'] += 1
     return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
Ejemplo n.º 27
0
    def test_involvement(self):
        with app.app_context():
            self.login()
            with app.test_request_context():
                app.preprocess_request()
                actor_id = EntityMapper.insert('E21', 'Captain Miller').id
                event_id = EntityMapper.insert('E8', 'Event Horizon').id
                involvement_id = NodeMapper.get_hierarchy_by_name(
                    'Involvement').id

            # add involvement
            rv = self.app.get(url_for('involvement_insert',
                                      origin_id=actor_id))
            assert b'Involvement' in rv.data
            data = {
                'event': '[' + str(event_id) + ']',
                'activity': 'P11',
                involvement_id: involvement_id
            }
            rv = self.app.post(url_for('involvement_insert',
                                       origin_id=actor_id),
                               data=data,
                               follow_redirects=True)
            assert b'Event Horizon' in rv.data
            data = {
                'actor': '[' + str(actor_id) + ']',
                'continue_': 'yes',
                'activity': 'P22'
            }
            rv = self.app.post(url_for('involvement_insert',
                                       origin_id=event_id),
                               data=data,
                               follow_redirects=True)
            assert b'Event Horizon' in rv.data
            self.app.get(url_for('event_view', id_=event_id))

            # update involvement
            with app.test_request_context():
                app.preprocess_request()
                link_id = LinkMapper.get_links(event_id, 'P22')[0].id
            rv = self.app.get(
                url_for('involvement_update', id_=link_id, origin_id=event_id))
            assert b'Captain' in rv.data
            rv = self.app.post(url_for('involvement_update',
                                       id_=link_id,
                                       origin_id=actor_id),
                               data={
                                   'description':
                                   'Infinite Space - Infinite Terror',
                                   'activity': 'P23'
                               },
                               follow_redirects=True)
            assert b'Infinite Space - Infinite Terror' in rv.data
            self.app.get(url_for('event_view', id_=event_id))
Ejemplo n.º 28
0
 def search(term, codes, description=False, own=False):
     sql = EntityMapper.sql
     if own:
         sql += " LEFT JOIN web.user_log ul ON e.id = ul.entity_id "
     sql += " WHERE LOWER(e.name) LIKE LOWER(%(term)s)"
     sql += " OR lower(e.description) LIKE lower(%(term)s) AND " if description else " AND "
     sql += " ul.user_id = %(user_id)s AND " if own else ''
     sql += " e.class_code IN %(codes)s"
     sql += " GROUP BY e.id ORDER BY e.name"
     g.cursor.execute(sql, {'term': '%' + term + '%', 'codes': tuple(codes),
                            'user_id': current_user.id})
     debug_model['div sql'] += 1
     entities = []
     for row in g.cursor.fetchall():
         if row.class_code == 'E82':  # If found in actor alias
             entities.append(LinkMapper.get_linked_entity(row.id, 'P131', True))
         elif row.class_code == 'E41':  # If found in place alias
             entities.append(LinkMapper.get_linked_entity(row.id, 'P1', True))
         else:
             entities.append(Entity(row))
     return entities
Ejemplo n.º 29
0
 def link_string(self,
                 code: str,
                 range_: str,
                 description: Optional[str] = None,
                 inverse: bool = False) -> List[int]:
     # range_ string from a form, can be empty, an int or an int list presentation
     # e.g. '', '1', '[]', '[1, 2]'
     ids = ast.literal_eval(range_)
     ids = [int(id_)
            for id_ in ids] if isinstance(ids, list) else [int(ids)]
     return LinkMapper.insert(self, code, EntityMapper.get_by_ids(ids),
                              description, inverse)
Ejemplo n.º 30
0
def admin_check_links(check=None):
    table = None
    if check:
        table = {
            'id': 'check',
            'header': ['domain', 'property', 'range'],
            'data': []
        }
        for result in LinkMapper.check_links():  # pragma: no cover
            table['data'].append(
                [result['domain'], result['property'], result['range']])
    return render_template('admin/check_links.html', table=table)
Ejemplo n.º 31
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)
Ejemplo n.º 32
0
def involvement_update(id_: int, origin_id: int) -> str:
    link_ = LinkMapper.get_by_id(id_)
    event = EntityMapper.get_by_id(link_.domain.id)
    actor = EntityMapper.get_by_id(link_.range.id)
    origin = event if origin_id == event.id else actor
    form = build_form(ActorForm, 'Involvement', link_, request)
    form.save.label.text = _('save')
    del form.actor, form.event, form.insert_and_continue
    form.activity.choices = [('P11', g.properties['P11'].name)]
    if event.class_.code in ['E7', 'E8']:
        form.activity.choices.append(('P14', g.properties['P14'].name))
    if event.class_.code == 'E8':
        form.activity.choices.append(('P22', g.properties['P22'].name))
        form.activity.choices.append(('P23', g.properties['P23'].name))
    if form.validate_on_submit():
        g.cursor.execute('BEGIN')
        try:
            link_.delete()
            link_ = LinkMapper.get_by_id(
                event.link(form.activity.data, actor, form.description.data))
            link_.set_dates(form)
            link_.type = get_link_type(form)
            link_.update()
            g.cursor.execute('COMMIT')
        except Exception as e:  # pragma: no cover
            g.cursor.execute('ROLLBACK')
            logger.log('error', 'database', 'transaction failed', e)
            flash(_('error transaction'), 'error')
        tab = 'actor' if origin.view_name == 'event' else 'event'
        return redirect(
            url_for(origin.view_name + '_view', id_=origin.id) + '#tab-' + tab)
    form.activity.data = link_.property.code
    form.description.data = link_.description
    form.populate_dates(link_)
    return render_template(
        'involvement/update.html',
        origin=origin,
        form=form,
        linked_object=event if origin_id != event.id else actor)
    def test_member(self):
        with app.app_context():
            self.login()
            with app.test_request_context():
                app.preprocess_request()
                actor_id = EntityMapper.insert('E21', 'Ripley').id
                group_id = EntityMapper.insert('E74', 'Space Marines').id

            # Add membership
            rv = self.app.get(url_for('member_insert', origin_id=group_id))
            assert b'Actor Function' in rv.data
            data = {'group': '[' + str(group_id) + ']'}
            rv = self.app.post(
                url_for('membership_insert', origin_id=actor_id), data=data, follow_redirects=True)
            assert b'Space Marines' in rv.data
            data = {'group': '[' + str(group_id) + ']', 'continue_': 'yes'}
            rv = self.app.post(
                url_for('membership_insert', origin_id=actor_id), data=data, follow_redirects=True)
            assert b'Space Marines' in rv.data

            rv = self.app.post(
                url_for('membership_insert', origin_id=group_id), data=data, follow_redirects=True)
            assert b"Can't link to itself" in rv.data
            rv = self.app.post(url_for('member_insert', origin_id=actor_id),
                               data={'actor': '[' + str(actor_id) + ']'}, follow_redirects=True)
            assert b"Can't link to itself" in rv.data

            # Add member to group
            data = {'actor': '[' + str(actor_id) + ']'}
            rv = self.app.post(
                url_for('member_insert', origin_id=group_id), data=data, follow_redirects=True)
            assert b'Ripley' in rv.data
            data['continue_'] = 'yes'
            rv = self.app.post(
                url_for('member_insert', origin_id=group_id), data=data, follow_redirects=True)
            assert b'Ripley' in rv.data

            # Update
            with app.test_request_context():
                app.preprocess_request()
                link_id = LinkMapper.get_links(group_id, 'P107')[0].id
            rv = self.app.get(url_for('member_update', id_=link_id, origin_id=group_id))
            assert b'Ripley' in rv.data
            rv = self.app.post(
                url_for('member_update', id_=link_id, origin_id=group_id),
                data={'description': 'We are here to help you.'},
                follow_redirects=True)
            assert b'here to help' in rv.data
Ejemplo n.º 34
0
def save(form, event=None, code=None, origin=None):
    g.cursor.execute('BEGIN')
    try:
        log_action = 'insert'
        if event:
            log_action = 'update'
            event.delete_links(['P117', 'P7', 'P24'])
        else:
            event = EntityMapper.insert(code, form.name.data)
        event.name = form.name.data
        event.description = form.description.data
        event.update()
        event.save_dates(form)
        event.save_nodes(form)
        if form.event.data:
            entity = EntityMapper.get_by_id(form.event.data)
            event.link('P117', entity)
        if form.place.data:
            place = LinkMapper.get_linked_entity(int(form.place.data), 'P53')
            event.link('P7', place)
        if event.class_.code == 'E8' and form.given_place.data:  # Link place for acquisition
            places = [EntityMapper.get_by_id(i) for i in ast.literal_eval(form.given_place.data)]
            event.link('P24', places)
        url = url_for('event_view', id_=event.id)
        if origin:
            url = url_for(origin.view_name + '_view', id_=origin.id) + '#tab-event'
            if origin.view_name == 'reference':
                link_id = origin.link('P67', event)
                url = url_for('reference_link_update', link_id=link_id, origin_id=origin.id)
            elif origin.view_name == 'source':
                origin.link('P67', event)
            elif origin.view_name == 'actor':
                link_id = event.link('P11', origin)
                url = url_for('involvement_update', id_=link_id, origin_id=origin.id)
            elif origin.view_name == 'file':
                origin.link('P67', event)
        if form.continue_.data == 'yes':
            url = url_for('event_insert', code=code, origin_id=origin.id if origin else None)
        g.cursor.execute('COMMIT')
        logger.log_user(event.id, log_action)
        flash(_('entity created') if log_action == 'insert' else _('info update'), 'info')
    except Exception as e:  # pragma: no cover
        g.cursor.execute('ROLLBACK')
        logger.log('error', 'database', 'transaction failed', e)
        flash(_('error transaction'), 'error')
        url = url_for('event_index')
    return url
def reference_link_update(link_id, origin_id):
    link_ = LinkMapper.get_by_id(link_id)
    origin = EntityMapper.get_by_id(origin_id)
    form = AddReferenceForm()
    form.save.label.text = _('save')
    del form.reference
    if form.validate_on_submit():
        link_.description = form.page.data
        link_.update()
        flash(_('info update'), 'info')
        tab = '#tab-reference'
        if origin.view_name == 'reference':
            tab = '#tab-' + link_.range.view_name
        return redirect(url_for(origin.view_name + '_view', id_=origin.id) + tab)
    form.page.data = link_.description
    linked_object = link_.domain if link_.domain.id != origin.id else link_.range
    return render_template('reference/link-update.html', origin=origin, form=form,
                           linked_object=linked_object)
    def test_involvement(self):
        with app.app_context():
            self.login()
            rv = self.app.post(url_for('event_insert', code='E8'),
                               data={
                                    'name': 'Event Horizon',
                                    'date_begin_year': '1949',
                                    'date_begin_month': '10',
                                    'date_begin_day': '8',
                                    'date_end_year': '1951'})
            event_id = int(rv.location.split('/')[-1])
            with app.test_request_context():
                app.preprocess_request()
                actor_id = EntityMapper.insert('E21', 'Captain Miller').id
                involvement_id = NodeMapper.get_hierarchy_by_name('Involvement').id

            # Add involvement
            rv = self.app.get(url_for('involvement_insert', origin_id=actor_id))
            assert b'Involvement' in rv.data
            data = {'event': '[' + str(event_id) + ']', 'activity': 'P11',
                    involvement_id: involvement_id}
            rv = self.app.post(url_for('involvement_insert', origin_id=actor_id), data=data,
                               follow_redirects=True)
            assert b'Event Horizon' in rv.data
            data = {'actor': '[' + str(actor_id) + ']', 'continue_': 'yes', 'activity': 'P22'}
            rv = self.app.post(url_for('involvement_insert', origin_id=event_id), data=data,
                               follow_redirects=True)
            assert b'Event Horizon' in rv.data
            self.app.get(url_for('event_view', id_=event_id))

            # Update involvement
            with app.test_request_context():
                app.preprocess_request()
                link_id = LinkMapper.get_links(event_id, 'P22')[0].id
            rv = self.app.get(url_for('involvement_update', id_=link_id, origin_id=event_id))
            assert b'Captain' in rv.data
            rv = self.app.post(
                url_for('involvement_update', id_=link_id, origin_id=actor_id),
                data={'description': 'Infinite Space - Infinite Terror', 'activity': 'P23'},
                follow_redirects=True)
            assert b'Infinite Space - Infinite Terror' in rv.data
            self.app.get(url_for('event_view', id_=event_id))
Ejemplo n.º 37
0
 def test_dates(self) -> None:
     self.login()
     with app.app_context():
         with app.test_request_context():
             app.preprocess_request()
             # Create invalid dates for an actor and a relation link
             person = EntityMapper.insert('E21', 'Person')
             event = EntityMapper.insert('E7', 'Event')
             person.begin_from = '2018-01-31'
             person.begin_to = '2018-01-01'
             person.update()
             involvement = LinkMapper.get_by_id(event.link('P11', person))
             involvement.begin_from = '2017-01-31'
             involvement.begin_to = '2017-01-01'
             involvement.end_from = '2017-01-01'
             involvement.update()
         rv = self.app.get(url_for('admin_check_dates'))
         assert b'Invalid dates <span class="tab-counter">1' in rv.data
         assert b'Invalid link dates <span class="tab-counter">1' in rv.data
         assert b'Invalid involvement dates <span class="tab-counter">1' in rv.data
Ejemplo n.º 38
0
 def invalid_involvement_dates() -> list:
     """ Search invalid event participation dates and return the actors
         e.g. attending person was born after the event ended"""
     from openatlas.models.link import LinkMapper
     sql = """
         SELECT l.id FROM model.entity actor
         JOIN model.link l ON actor.id = l.range_id
             AND l.property_code IN ('P11', 'P14', 'P22', 'P23')
         JOIN model.entity event ON l.domain_id = event.id
         WHERE
             (actor.begin_from IS NOT NULL AND l.end_from IS NOT NULL
                 AND actor.begin_from > l.end_from)
             OR (actor.begin_to IS NOT NULL AND l.end_to IS NOT NULL
                 AND actor.begin_to > l.end_to)
             OR (actor.begin_from IS NOT NULL AND event.end_from IS NOT NULL
                 AND actor.begin_from > event.end_from)
             OR (actor.begin_to IS NOT NULL AND event.end_to IS NOT NULL
                 AND actor.begin_to > event.end_to);"""
     g.execute(sql)
     return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
Ejemplo n.º 39
0
def reference_link_update(link_id, origin_id):
    link_ = LinkMapper.get_by_id(link_id)
    origin = EntityMapper.get_by_id(origin_id)
    view_name = get_view_name(origin)
    form = AddReferenceForm()
    form.save.label.text = _('save')
    del form.reference
    if form.validate_on_submit():
        link_.description = form.page.data
        link_.update()
        flash(_('info update'), 'info')
        tab = '#tab-' + get_view_name(
            link_.range) if view_name == 'reference' else '#tab-reference'
        return redirect(url_for(view_name + '_view', id_=origin.id) + tab)
    form.page.data = link_.description
    return render_template('reference/link-update.html',
                           origin=origin,
                           linked_object=link_.domain
                           if link_.domain.id != origin.id else link_.range,
                           form=form,
                           class_name=view_name)
Ejemplo n.º 40
0
def place_delete(id_):
    entity = EntityMapper.get_by_id(id_)
    if entity.get_linked_entities('P46'):
        flash(_('Deletion not possible if subunits exists'), 'error')
        return redirect(url_for('place_view', id_=id_))
    system_type = entity.system_type
    parent = None if system_type == 'place' else LinkMapper.get_linked_entity(id_, 'P46', True)
    g.cursor.execute('BEGIN')
    try:
        EntityMapper.delete(id_)
        logger.log_user(id_, 'delete')
        g.cursor.execute('COMMIT')
    except Exception as e:  # pragma: no cover
        g.cursor.execute('ROLLBACK')
        logger.log('error', 'database', 'transaction failed', e)
        flash(_('error transaction'), 'error')
    flash(_('entity deleted'), 'info')
    url = url_for('place_index')
    if parent:
        url = url_for('place_view', id_=parent.id) + '#tab-' + system_type
    return redirect(url)
Ejemplo n.º 41
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)
Ejemplo n.º 42
0
 def invalid_involvement_dates():
     """ Search invalid event participation dates and return the actors
         e.g. attending person was born after the event ended
     """
     from openatlas.models.link import LinkMapper
     sql = """
         SELECT l.id FROM model.entity actor
         JOIN model.link l ON actor.id = l.range_id
             AND l.property_code IN ('P11', 'P14', 'P22', 'P23')
         JOIN model.entity event ON l.domain_id = event.id
         WHERE
             (actor.begin_from IS NOT NULL AND l.end_from IS NOT NULL
                 AND actor.begin_from > l.end_from)
             OR (actor.begin_to IS NOT NULL AND l.end_to IS NOT NULL
                 AND actor.begin_to > l.end_to)
             OR (actor.begin_from IS NOT NULL AND event.end_from IS NOT NULL
                 AND actor.begin_from > event.end_from)
             OR (actor.begin_to IS NOT NULL AND event.end_to IS NOT NULL
                 AND actor.begin_to > event.end_to);"""
     g.cursor.execute(sql)
     debug_model['div sql'] += 1
     return [LinkMapper.get_by_id(row.id) for row in g.cursor.fetchall()]
    def test_relation(self):
        with app.app_context():
            self.login()
            with app.test_request_context():
                app.preprocess_request()
                actor_id = EntityMapper.insert('E21', 'Connor MacLeod').id
                related_id = EntityMapper.insert('E21', 'The Kurgan').id

            # Add relationship
            rv = self.app.get(url_for('relation_insert', origin_id=actor_id))
            assert b'Actor Actor Relation' in rv.data
            relation_id = NodeMapper.get_hierarchy_by_name('Actor Actor Relation').id
            relation_sub_id = g.nodes[relation_id].subs[0]
            data = {
                'actor': '[' + str(related_id) + ']',
                relation_id: relation_sub_id,
                'inverse': None,
                'date_begin_year': '-1949',
                'date_begin_month': '10',
                'date_begin_day': '8',
                'date_begin_year2': '-1948',
                'date_end_year': '2049',
                'date_end_year2': '2050'}
            rv = self.app.post(
                url_for('relation_insert', origin_id=actor_id), data=data, follow_redirects=True)
            assert b'The Kurgan' in rv.data
            rv = self.app.get(url_for('node_view', id_=relation_sub_id))
            assert b'Connor' in rv.data
            data['continue_'] = 'yes'
            data['inverse'] = True
            rv = self.app.post(
                url_for('relation_insert', origin_id=actor_id), data=data, follow_redirects=True)
            assert b'The Kurgan' in rv.data
            rv = self.app.get(url_for('actor_view', id_=actor_id))
            assert b'The Kurgan' in rv.data

            rv = self.app.post(
                url_for('relation_insert', origin_id=related_id), data=data, follow_redirects=True)
            assert b"Can't link to itself." in rv.data

            # Relation types
            rv = self.app.get(url_for('node_move_entities', id_=relation_sub_id))
            assert b'The Kurgan' in rv.data

            # Update relationship
            with app.test_request_context():
                app.preprocess_request()
                link_id = LinkMapper.get_links(actor_id, 'OA7')[0].id
                link_id2 = LinkMapper.get_links(actor_id, 'OA7', True)[0].id
            rv = self.app.get(url_for('relation_update', id_=link_id, origin_id=related_id))
            assert b'Connor' in rv.data
            rv = self.app.post(
                url_for('relation_update', id_=link_id, origin_id=actor_id),
                data={'description': 'There can be only one!', 'inverse': True},
                follow_redirects=True)
            assert b'only one' in rv.data
            rv = self.app.post(
                url_for('relation_update', id_=link_id2, origin_id=actor_id),
                data={'description': 'There can be only one!', 'inverse': None},
                follow_redirects=True)
            assert b'only one' in rv.data
Ejemplo n.º 44
0
 def get_linked_entities(self, code,
                         inverse: Optional[bool] = False,
                         nodes: Optional[bool] = False):
     return LinkMapper.get_linked_entities(self, code, inverse=inverse, nodes=nodes)
Ejemplo n.º 45
0
 def get_links(self, code, inverse=False):
     return LinkMapper.get_links(self, code, inverse)
Ejemplo n.º 46
0
 def delete_links(self, codes) -> None:
     LinkMapper.delete_by_codes(self, codes)
Ejemplo n.º 47
0
 def get_links(self, code, inverse: Optional[bool] = False):
     return LinkMapper.get_links(self, code, inverse)
Ejemplo n.º 48
0
 def link(self, code, range_, description: Optional[str] = None,
          inverse: Optional[bool] = False):
     return LinkMapper.insert(self, code, range_, description, inverse)
Ejemplo n.º 49
0
def link_delete(id_, origin_id):
    LinkMapper.delete(id_)
    flash(_('link removed'), 'info')
    origin = EntityMapper.get_by_id(origin_id)
    return redirect(url_for(origin.view_name + '_view', id_=origin.id))
Ejemplo n.º 50
0
 def link(self, code, range_, description=None, inverse=False):
     return LinkMapper.insert(self, code, range_, description, inverse)
Ejemplo n.º 51
0
 def get_linked_entities(self, code, inverse=False):
     return LinkMapper.get_linked_entities(self, code, inverse)
Ejemplo n.º 52
0
    def search(form):
        if not form.term.data:
            return []
        sql = EntityMapper.build_sql() + """
            {user_clause} WHERE (LOWER(e.name) LIKE LOWER(%(term)s) {description_clause})
            AND {user_clause2} (""".format(
            user_clause="""
                LEFT JOIN web.user_log ul ON e.id = ul.entity_id """ if form.own.data else '',
            description_clause="""
                OR lower(e.description) LIKE lower(%(term)s) """ if form.desc.data else '',
            user_clause2=' ul.user_id = %(user_id)s AND ' if form.own.data else '')
        sql_where = []
        for name in form.classes.data:
            if name in ['source', 'event']:
                sql_where.append("e.class_code IN ({codes})".format(
                    codes=str(app.config['CLASS_CODES'][name])[1:-1]))
            elif name == 'actor':
                codes = app.config['CLASS_CODES'][name] + ['E82']  # Add alias
                sql_where.append(" e.class_code IN ({codes})".format(codes=str(codes)[1:-1]))
            elif name == 'place':
                sql_where.append("(e.class_code = 'E41' OR e.system_type = 'place')")
            elif name == 'feature':
                sql_where.append("e.system_type = 'feature'")
            elif name == 'stratigraphic unit':
                sql_where.append("e.system_type = 'stratigraphic unit'")
            elif name == 'find':
                sql_where.append("e.class_code = 'E22'")
            elif name == 'reference':
                sql_where.append(" e.class_code IN ({codes}) AND e.system_type != 'file'".format(
                    codes=str(app.config['CLASS_CODES']['reference'])[1:-1]))
            elif name == 'file':
                sql_where.append(" e.system_type = 'file'")
        sql += ' OR '.join(sql_where) + ") GROUP BY e.id ORDER BY e.name;"
        g.cursor.execute(sql, {'term': '%' + form.term.data + '%', 'user_id': current_user.id})
        debug_model['div sql'] += 1

        # Prepare date filter
        from_date = DateMapper.form_to_datetime64(form.begin_year.data, form.begin_month.data,
                                                  form.begin_day.data)
        to_date = DateMapper.form_to_datetime64(form.end_year.data, form.end_month.data,
                                                form.end_day.data, True)

        # Refill form in case dates were completed
        if from_date:
            string = str(from_date)
            if string.startswith('-') or string.startswith('0000'):
                string = string[1:]
            parts = string.split('-')
            form.begin_month.raw_data = None
            form.begin_day.raw_data = None
            form.begin_month.data = int(parts[1])
            form.begin_day.data = int(parts[2])

        if to_date:
            string = str(to_date)
            if string.startswith('-') or string.startswith('0000'):
                string = string[1:]  # pragma: no cover
            parts = string.split('-')
            form.end_month.raw_data = None
            form.end_day.raw_data = None
            form.end_month.data = int(parts[1])
            form.end_day.data = int(parts[2])

        entities = []
        for row in g.cursor.fetchall():
            entity = None
            if row.class_code == 'E82':  # If found in actor alias
                entity = LinkMapper.get_linked_entity(row.id, 'P131', True)
            elif row.class_code == 'E41':  # If found in place alias
                entity = LinkMapper.get_linked_entity(row.id, 'P1', True)
            elif row.class_code == 'E18':
                if row.system_type in form.classes.data:
                    entity = Entity(row)
            else:
                entity = Entity(row)

            if not entity:  # pragma: no cover
                continue

            if not from_date and not to_date:
                entities.append(entity)
                continue

            # Date criteria present but entity has no dates
            if not entity.begin_from and not entity.begin_to and not entity.end_from \
                    and not entity.end_to:
                if form.include_dateless.data:  # Include dateless entities
                    entities.append(entity)
                continue

            # Check date criteria
            dates = [entity.begin_from, entity.begin_to, entity.end_from, entity.end_to]
            begin_check_ok = False
            if not from_date:
                begin_check_ok = True  # pragma: no cover
            else:
                for date in dates:
                    if date and date >= from_date:
                        begin_check_ok = True

            end_check_ok = False
            if not to_date:
                end_check_ok = True  # pragma: no cover
            else:
                for date in dates:
                    if date and date <= to_date:
                        end_check_ok = True

            if begin_check_ok and end_check_ok:
                entities.append(entity)

        return {d.id: d for d in entities}.values()  # Remove duplicates before returning