Exemplo n.º 1
0
def hierarchy_insert(category: str) -> Union[str, Response]:
    form = build_form('hierarchy', code=category)
    form.classes.choices = Type.get_class_choices()
    if form.validate_on_submit():
        if Type.check_hierarchy_exists(form.name.data):
            flash(_('error name exists'), 'error')
            return render_template('display_form.html', form=form)
        try:
            Transaction.begin()
            type_ = Entity.insert('type', sanitize(form.name.data))
            Type.insert_hierarchy(
                type_,  # type: ignore
                category,
                form.classes.data,
                is_multiple(form, category))
            type_.update(process_form_data(form, type_))
            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(_('entity created'), 'info')
        return redirect(f"{url_for('type_index')}#menu-tab-{category}")
    return render_template(
        'display_form.html',
        form=form,
        manual_page='entity/type',
        title=_('types'),
        crumbs=[
            [_('types'), url_for('type_index')],
            f'+ {uc_first(_(category))}'])
Exemplo n.º 2
0
def type_move_entities(id_: int) -> Union[str, Response]:
    type_ = g.types[id_]
    root = g.types[type_.root[0]]
    if root.category == 'value':
        abort(403)  # pragma: no cover
    form = build_move_form(type_)
    if form.validate_on_submit():
        Transaction.begin()
        Type.move_entities(type_,
                           getattr(form, str(root.id)).data,
                           form.checkbox_values.data)
        Transaction.commit()
        flash(_('Entities were updated'), 'success')
        return redirect(f"{url_for('type_index')}"
                        f"#menu-tab-{type_.category}_collapse-{root.id}")
    getattr(form, str(root.id)).data = type_.id
    return render_template('type/move.html',
                           table=Table(header=['#', _('selection')],
                                       rows=[[item, item.label.text]
                                             for item in form.selection]),
                           root=root,
                           form=form,
                           entity=type_,
                           crumbs=[[_('types'),
                                    url_for('type_index')], root, type_,
                                   _('move entities')])
Exemplo n.º 3
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')])
Exemplo n.º 4
0
def remove_class(id_: int, class_name: str) -> Response:
    root = g.types[id_]
    if Type.get_form_count(root, class_name):
        abort(403)  # pragma: no cover
    try:
        Type.remove_class_from_hierarchy(class_name, root.id)
        flash(_('info update'), 'info')
    except Exception as e:  # pragma: no cover
        logger.log('error', 'database', 'remove class from hierarchy failed', e)
        flash(_('error database'), 'error')
    return redirect(url_for('hierarchy_update', id_=id_))
Exemplo n.º 5
0
def before_request() -> None:
    from openatlas.models.openatlas_class import (OpenatlasClass,
                                                  view_class_mapping)
    from openatlas.models.cidoc_property import CidocProperty
    from openatlas.models.cidoc_class import CidocClass
    from openatlas.models.type import Type
    from openatlas.models.settings import Settings
    from openatlas.models.reference_system import ReferenceSystem

    if request.path.startswith('/static'):  # pragma: no cover
        return  # Avoid overhead for files if not using Apache with static alias
    open_connection(app.config)
    g.settings = Settings.get_settings()
    session['language'] = get_locale()
    g.cidoc_classes = CidocClass.get_all()
    g.properties = CidocProperty.get_all()
    g.classes = OpenatlasClass.get_all()
    g.types = Type.get_all()
    g.reference_systems = ReferenceSystem.get_all()
    g.view_class_mapping = view_class_mapping
    g.class_view_mapping = OpenatlasClass.get_class_view_mapping()
    g.table_headers = OpenatlasClass.get_table_headers()
    g.file_stats = get_file_stats()

    # Set max file upload in MB
    app.config['MAX_CONTENT_LENGTH'] = \
        g.settings['file_upload_max_size'] * 1024 * 1024

    if request.path.startswith('/api/'):
        ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)
        if not current_user.is_authenticated \
                and not g.settings['api_public'] \
                and ip not in app.config['ALLOWED_IPS']:
            raise AccessDeniedError  # pragma: no cover
Exemplo n.º 6
0
def type_delete_recursive(id_: int) -> Union[str, Response]:
    class DeleteRecursiveTypesForm(FlaskForm):
        confirm_delete = BooleanField(
            _("I'm sure to delete this type, it's subs and links"),
            default=False,
            validators=[InputRequired()])
        save = SubmitField(_('delete types and remove all links'))

    type_ = g.types[id_]
    root = g.types[type_.root[0]] if type_.root else None
    if type_.category in ('standard', 'system', 'place') and not root:
        abort(403)
    form = DeleteRecursiveTypesForm()
    if form.validate_on_submit() and form.confirm_delete.data:
        for sub_id in Type.get_all_sub_ids(type_):
            g.types[sub_id].delete()
        type_.delete()
        flash(_('types deleted'), 'info')
        logger.log_user(id_, 'Recursive type delete')
        return redirect(
            url_for('view', id_=root.id) if root else url_for('type_index'))
    tabs = {
        'info':
        Tab('info',
            content=_(
                'Warning: this type has subs and/or links to entities '
                '(see tabs). Please check if you want to delete these subs '
                'and links too.'),
            form=form),
        'subs':
        Tab('subs', entity=type_),
        'entities':
        Tab('entities', entity=type_)
    }
    for sub_id in Type.get_all_sub_ids(type_):
        sub = g.types[sub_id]
        tabs['subs'].table.rows.append([link(sub), sub.count, sub.description])
    for item in get_entities_linked_to_type_recursive(type_.id, []):
        data = [link(item), item.class_.label, item.description]
        tabs['entities'].table.rows.append(data)
    crumbs = [[_('types'), url_for('type_index')]]
    if root:
        crumbs += [g.types[type_id] for type_id in type_.root]
    crumbs += [type_, _('delete')]
    return render_template('tabs.html', tabs=tabs, crumbs=crumbs)
Exemplo n.º 7
0
 def __call__(self, field: TreeField, **kwargs: Any) -> TreeMultiSelect:
     data: list[int] = []
     if field.data:
         data = ast.literal_eval(field.data) \
             if isinstance(field.data, str) else field.data
     return super().__call__(field, **kwargs) + render_template(
         'forms/tree_multi_select.html',
         field=field,
         root=g.types[int(field.id)],
         selection=sorted([g.types[id_].name for id_ in data]),
         data=Type.get_tree_data(int(field.id), data))
Exemplo n.º 8
0
 def __call__(self, field: TreeField, **kwargs: Any) -> TreeSelect:
     selection = ''
     selected_ids = []
     if field.data:
         field.data = field.data[0] \
             if isinstance(field.data, list) else field.data
         selection = g.types[int(field.data)].name
         selected_ids.append(g.types[int(field.data)].id)
     return super().__call__(field, **kwargs) + render_template(
         'forms/tree_select.html',
         field=field,
         selection=selection,
         data=Type.get_tree_data(int(field.id), selected_ids))
Exemplo n.º 9
0
 def get_node_overview() -> dict[str, dict[Entity, str]]:
     nodes: dict[str, Any] = {
         'standard': {},
         'custom': {},
         'place': {},
         'value': {},
         'system': {},
         'anthropology': {}
     }
     for node in g.types.values():
         if node.root:
             continue
         nodes[node.category][node.name] = GetNodeOverview.walk_tree(
             Type.get_types(node.name))
     return nodes
Exemplo n.º 10
0
def show_untyped_entities(id_: int) -> str:
    hierarchy = g.types[id_]
    table = Table(['name', 'class', 'first', 'last', 'description'])
    for entity in Type.get_untyped(hierarchy.id):
        table.rows.append([
            link(entity), entity.class_.label, entity.first, entity.last,
            entity.description
        ])
    return render_template('table.html',
                           entity=hierarchy,
                           table=table,
                           crumbs=[[_('types'),
                                    url_for('type_index')],
                                   link(hierarchy),
                                   _('untyped entities')])
Exemplo n.º 11
0
 def get_node_overview() -> dict[str, dict[Entity, str]]:
     nodes: dict[str, Any] = {
         'standard': [],
         'custom': [],
         'place': [],
         'value': [],
         'system': [],
         'anthropology': []}
     for node in g.types.values():
         if node.root:
             continue
         nodes[node.category].append({
             "id": node.id,
             "name": node.name,
             "viewClass": node.classes,
             "children":
                 GetTypeOverview.walk_tree(Type.get_types(node.name))})
     return nodes
Exemplo n.º 12
0
 def get(filename: str) -> Response:  # pragma: no cover
     entity = Entity.get_by_id(int(Pathlib_path(filename).stem), types=True)
     license_ = None
     for node in entity.types:
         if node.root and node.root[0] == Type.get_hierarchy('License').id:
             license_ = node.name
     if not license_:
         raise AccessDeniedError
     parser = image.parse_args()
     if parser['download']:
         return send_file(
             f"{app.config['UPLOAD_DIR']}/{filename}",
             as_attachment=True)
     if parser['image_size'] and check_processed_image(filename):
         size = app.config['IMAGE_SIZE'][parser['image_size']]
         return send_from_directory(
             f"{app.config['RESIZED_IMAGES']}/{size}",
             filename)
     return send_from_directory(app.config['UPLOAD_DIR'], filename)
Exemplo n.º 13
0
def type_index() -> str:
    types: dict[str, dict[Entity, str]] = {
        'standard': {},
        'custom': {},
        'place': {},
        'value': {},
        'system': {}
    }
    for type_ in [type_ for type_ in g.types.values() if not type_.root]:
        if type_.category not in types:
            continue  # pragma: no cover, remove after anthropology features
        types[type_.category][type_] = render_template(
            'forms/tree_select_item.html',
            name=sanitize(type_.name),
            data=walk_tree(Type.get_types(type_.name)))
    return render_template('type/index.html',
                           types=types,
                           title=_('types'),
                           crumbs=[_('types')])
Exemplo n.º 14
0
 def check_single_type_duplicates() -> list[dict[str, Any]]:
     from openatlas.models.type import Type
     from openatlas.models.entity import Entity
     data = []
     for type_ in g.types.values():
         if type_.root or type_.multiple or type_.category == 'value':
             continue  # pragma: no cover
         type_ids = Type.get_all_sub_ids(type_)
         if not type_ids:
             continue  # pragma: no cover
         for id_ in Db.check_single_type_duplicates(type_ids):
             offending_types = []
             entity = Entity.get_by_id(id_, types=True)
             for entity_types in entity.types:
                 if g.types[entity_types.root[0]].id != type_.id:
                     continue  # pragma: no cover
                 offending_types.append(entity_types)
             data.append({
                 'entity': entity,
                 'type': type_,
                 'offending_types': offending_types
             })
     return data
Exemplo n.º 15
0
def add_reference_systems(form: Any, class_: str) -> None:
    precisions = [('', '')] + [
        (str(g.types[id_].id), g.types[id_].name)
        for id_ in Type.get_hierarchy('External reference match').subs
    ]
    systems = list(g.reference_systems.values())
    systems.sort(key=lambda x: x.name.casefold())
    for system in systems:
        if class_ not in system.classes:
            continue
        setattr(
            form, f'reference_system_id_{system.id}',
            StringField(uc_first(system.name), [OptionalValidator()],
                        description=system.description,
                        render_kw={
                            'autocomplete': 'off',
                            'placeholder': system.placeholder
                        }))
        setattr(
            form, f'reference_system_precision_{system.id}',
            SelectField(_('precision'),
                        choices=precisions,
                        default=system.precision_default_id))
Exemplo n.º 16
0
 def test_duplicates(self) -> None:
     with app.app_context():
         with app.test_request_context():
             app.preprocess_request()  # type: ignore
             event = Entity.insert('acquisition', 'Event Horizon')
             source = Entity.insert('source', 'Tha source')
             source.link('P67', event)
             source.link('P67', event)
             source_type = Type.get_hierarchy('Source')
             source.link('P2', g.types[source_type.subs[0]])
             source.link('P2', g.types[source_type.subs[1]])
         rv = self.app.get(url_for('admin_check_link_duplicates'))
         assert b'Event Horizon' in rv.data
         rv = self.app.get(
             url_for('admin_check_link_duplicates', delete='delete'),
             follow_redirects=True)
         assert b'Remove' in rv.data
         rv = self.app.get(
             url_for(
                 'admin_delete_single_type_duplicate',
                 entity_id=source.id,
                 type_id=source_type.subs[0]),
             follow_redirects=True)
         assert b'Congratulations, everything looks fine!' in rv.data
Exemplo n.º 17
0
    def test_actor(self) -> None:
        with app.app_context():
            rv: Any = self.app.get(url_for('index', view='actor'))
            assert b'No entries' in rv.data
            rv = self.app.post(url_for('insert', class_='place'),
                               data={
                                   'name': 'Captain Miller',
                                   self.precision_geonames: '',
                                   self.precision_wikidata: ''
                               })
            residence_id = rv.location.split('/')[-1]
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                sex_type = Type.get_hierarchy('Sex')
                sex_type_sub_1 = g.types[sex_type.subs[0]]
                sex_type_sub_2 = g.types[sex_type.subs[1]]
                event = Entity.insert('acquisition', 'Event Horizon')
                source = Entity.insert('source', 'Necronomicon')

            # Actor insert
            rv = self.app.get(url_for('insert', class_='person'))
            assert b'+ Person' in rv.data
            self.app.get(
                url_for('insert', class_='person', origin_id=residence_id))
            data = {
                sex_type.id: sex_type_sub_1.id,
                'name': 'Sigourney Weaver',
                'alias-1': 'Ripley',
                'residence': residence_id,
                'begins_in': residence_id,
                'ends_in': residence_id,
                'description':
                'Susan Alexandra Weaver is an American actress.',
                'begin_year_from': '-1949',
                'begin_month_from': '10',
                'begin_day_from': '8',
                'begin_year_to': '-1948',
                'end_year_from': '2049',
                'end_year_to': '2050',
                self.precision_geonames: '',
                self.precision_wikidata: ''
            }
            rv = self.app.post(url_for('insert', class_='person'), data=data)
            actor_id = rv.location.split('/')[-1]
            self.app.post(url_for('insert', class_='group'), data=data)
            rv = self.app.post(url_for('insert',
                                       class_='person',
                                       origin_id=residence_id),
                               data=data,
                               follow_redirects=True)
            assert b'An entry has been created' in rv.data

            # Test actor types
            rv = self.app.get(url_for('view', id_=sex_type_sub_1.id))
            assert b'Susan' in rv.data
            rv = self.app.get(
                url_for('type_move_entities', id_=sex_type_sub_1.id))
            assert b'Sigourney' in rv.data
            rv = self.app.post(url_for('type_move_entities',
                                       id_=sex_type_sub_1.id),
                               follow_redirects=True,
                               data={
                                   sex_type.id: sex_type_sub_2.id,
                                   'selection': [actor_id],
                                   'checkbox_values': str([actor_id])
                               })
            assert b'Entities were updated' in rv.data
            rv = self.app.post(url_for('type_move_entities',
                                       id_=sex_type_sub_2.id),
                               follow_redirects=True,
                               data={
                                   sex_type.id: '',
                                   'selection': [actor_id],
                                   'checkbox_values': str([actor_id])
                               })
            assert b'Entities were updated' in rv.data
            self.app.post(url_for('insert',
                                  class_='person',
                                  origin_id=actor_id),
                          data=data)
            self.app.post(url_for('insert',
                                  class_='person',
                                  origin_id=event.id),
                          data=data)
            self.app.post(url_for('insert',
                                  class_='person',
                                  origin_id=source.id),
                          data=data)
            rv = self.app.post(url_for('insert', class_='external_reference'),
                               data={'name': 'https://openatlas.eu'})
            reference_id = rv.location.split('/')[-1]
            rv = self.app.post(url_for('insert',
                                       class_='person',
                                       origin_id=reference_id),
                               data=data,
                               follow_redirects=True)
            assert b'An entry has been created' in rv.data
            data['continue_'] = 'yes'
            rv = self.app.post(url_for('insert', class_='person'),
                               data=data,
                               follow_redirects=True)
            assert b'An entry has been created' in rv.data
            rv = self.app.get(url_for('index', view='actor'))
            assert b'Sigourney Weaver' in rv.data

            # Add to actor
            rv = self.app.get(url_for('entity_add_source', id_=actor_id))
            assert b'Link source' in rv.data
            rv = self.app.post(url_for('entity_add_source', id_=actor_id),
                               data={'checkbox_values': str([source.id])},
                               follow_redirects=True)
            assert b'Necronomicon' in rv.data

            rv = self.app.get(url_for('entity_add_reference', id_=actor_id))
            assert b'Link reference' in rv.data
            rv = self.app.post(url_for('entity_add_reference', id_=actor_id),
                               data={
                                   'reference': reference_id,
                                   'page': '777'
                               },
                               follow_redirects=True)
            assert b'777' in rv.data

            # Actor update
            rv = self.app.get(url_for('update', id_=actor_id))
            assert b'American actress' in rv.data
            data['name'] = 'Susan Alexandra Weaver'
            data['alias-1'] = 'Ripley1'
            data['end_year_from'] = ''
            data['end_year_to'] = ''
            data['begin_year_to'] = '1950'
            data['begin_day_from'] = ''
            rv = self.app.post(url_for('update', id_=actor_id),
                               data=data,
                               follow_redirects=True)
            assert b'Changes have been saved' in rv.data
            rv = self.app.post(url_for('ajax_bookmark'),
                               data={'entity_id': actor_id},
                               follow_redirects=True)
            assert b'Remove bookmark' in rv.data
            rv = self.app.get('/')
            assert b'Weaver' in rv.data
            rv = self.app.post(url_for('ajax_bookmark'),
                               data={'entity_id': actor_id},
                               follow_redirects=True)
            assert b'Bookmark' in rv.data
            rv = self.app.get(url_for('link_delete',
                                      origin_id=actor_id,
                                      id_=666),
                              follow_redirects=True)
            assert b'removed' in rv.data

            # Actor delete
            rv = self.app.get(
                url_for('index', view='actor', delete_id=actor_id))
            assert b'The entry has been deleted.' in rv.data
Exemplo n.º 18
0
 def get_type_tree() -> dict[int, Any]:
     return {
         id_: GetTypeTree.serialize_to_json(type_)
         for id_, type_ in Type.get_all().items()
     }
Exemplo n.º 19
0
    def test_type(self) -> None:
        with app.app_context():
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                actor_type = Type.get_hierarchy('Actor actor relation')
                dimension_type = Type.get_hierarchy('Dimensions')
                historical_type = Type.get_hierarchy('Historical place')
                sex_type = Type.get_hierarchy('Sex')
                place = insert_entity('Home', 'place')
                place.link('P2', g.types[dimension_type.subs[0]], '46')
                location = place.get_linked_entity_safe('P53')
                location.link('P89', g.types[historical_type.subs[0]])
            rv: Any = self.app.get(url_for('view', id_=historical_type.subs[0]))
            assert b'Historical place' in rv.data
            rv = self.app.get(url_for('type_index'))
            assert b'Actor actor relation' in rv.data
            rv = self.app.get(
                url_for('insert', class_='type', origin_id=actor_type.id))
            assert b'Actor actor relation' in rv.data
            data = {
                'name': 'My secret type',
                'name_inverse': 'Do I look inverse?',
                'description': 'Very important!'}
            rv = self.app.post(
                url_for('insert', class_='type', origin_id=actor_type.id),
                data=data)
            type_id = rv.location.split('/')[-1]
            rv = self.app.get(url_for('update', id_=type_id))
            assert b'My secret type' in rv.data and b'Super' in rv.data
            self.app.post(
                url_for('insert', class_='type', origin_id=sex_type.id),
                data=data)
            rv = self.app.post(
                url_for('update', id_=type_id),
                data=data,
                follow_redirects=True)
            assert b'Changes have been saved.' in rv.data

            # Insert and continue
            data['continue_'] = 'yes'
            rv = self.app.post(
                url_for('insert', class_='type', origin_id=actor_type.id),
                data=data,
                follow_redirects=True)
            assert b'An entry has been created' in rv.data
            data['continue_'] = ''

            # Forbidden system type
            rv = self.app.post(
                url_for('update', id_=actor_type.id),
                data=data,
                follow_redirects=True)
            assert b'Forbidden' in rv.data

            # Update with self as root
            data[str(actor_type.id)] = type_id
            rv = self.app.post(
                url_for('update', id_=type_id),
                data=data,
                follow_redirects=True)
            assert b'Type can't have itself as super' in rv.data

            # Update with sub as root
            rv = self.app.post(
                url_for('insert', class_='type', origin_id=actor_type.id),
                data=data)
            sub_type_id = rv.location.split('/')[-1].replace('type#tab-', '')
            data[str(actor_type.id)] = sub_type_id
            rv = self.app.post(
                url_for('update', id_=type_id),
                data=data,
                follow_redirects=True)
            assert b'Type can't have a sub as super' in rv.data

            # Custom type
            rv = self.app.get(
                url_for('view', id_=sex_type.id),
                follow_redirects=True)
            assert b'Male' in rv.data

            # Administrative unit
            admin_unit_id = Type.get_hierarchy('Administrative unit').id
            rv = self.app.get(
                url_for('view', id_=admin_unit_id), follow_redirects=True)
            assert b'Austria' in rv.data
            rv = self.app.post(
                url_for(
                    'insert',
                    class_='administrative_unit',
                    origin_id=g.types[admin_unit_id].subs[0]),
                data={'name': 'admin unit'},
                follow_redirects=True)
            assert b'An entry has been created' in rv.data

            # Value type
            rv = self.app.get(
                url_for('view', id_=dimension_type.id),
                follow_redirects=True)
            assert b'Height' in rv.data
            rv = self.app.get(url_for('view', id_=dimension_type.subs[0]))
            assert b'Unit' in rv.data
            rv = self.app.get(url_for('update', id_=dimension_type.subs[0]))
            assert b'Dimensions' in rv.data

            # Test parent value type view after creating a sub subtype
            rv = self.app.post(
                url_for(
                    'insert',
                    class_='type',
                    origin_id=dimension_type.subs[0]),
                data={
                    'name': "Sub sub type",
                    dimension_type.id: dimension_type.subs[0]},
                follow_redirects=True)
            assert b'An entry has been created' in rv.data
            rv = self.app.get(url_for('view', id_=dimension_type.subs[0]))
            assert b'Sub sub type' in rv.data

            # Untyped entities
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                actor = Entity.insert('person', 'Connor MacLeod')
            rv = self.app.get(url_for('show_untyped_entities', id_=sex_type.id))
            assert b'Connor MacLeod' in rv.data
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                actor.link('P2', g.types[sex_type.subs[0]])
            rv = self.app.get(url_for('show_untyped_entities', id_=sex_type.id))
            assert b'No entries' in rv.data

            # Delete
            rv = self.app.get(
                url_for('type_delete', id_=actor_type.id),
                follow_redirects=True)
            assert b'Forbidden' in rv.data
            rv = self.app.get(
                url_for('type_delete', id_=sub_type_id),
                follow_redirects=True)
            assert b'The entry has been deleted.' in rv.data
Exemplo n.º 20
0
def get_sub_ids(id_: int, subs: list[Any]) -> list[Any]:
    new_subs = Type.get_all_sub_ids(g.types[id_])
    subs.extend(new_subs)
    for sub in new_subs:
        get_sub_ids(sub, subs)
    return subs
Exemplo n.º 21
0
def admin_orphans() -> str:
    header = [
        'name', 'class', 'type', 'system type', 'created', 'updated',
        'description'
    ]
    tabs = {
        'orphans':
        Tab('orphans', table=Table(header)),
        'unlinked':
        Tab('unlinked', table=Table(header)),
        'types':
        Tab('type',
            table=Table(
                ['name', 'root'],
                [[link(type_), link(g.types[type_.root[0]])]
                 for type_ in Type.get_type_orphans()])),
        'missing_files':
        Tab('missing_files', table=Table(header)),
        'orphaned_files':
        Tab('orphaned_files', table=Table(['name', 'size', 'date', 'ext'])),
        'circular':
        Tab('circular_dependencies',
            table=Table(['entity'],
                        [[link(e)]
                         for e in Entity.get_entities_linked_to_itself()]))
    }

    for entity in filter(lambda x: not isinstance(x, ReferenceSystem),
                         Entity.get_orphans()):
        tabs['unlinked' if entity.class_.
             view else 'orphans'].table.rows.append([
                 link(entity),
                 link(entity.class_),
                 link(entity.standard_type), entity.class_.label,
                 format_date(entity.created),
                 format_date(entity.modified), entity.description
             ])

    # Orphaned file entities with no corresponding file
    entity_file_ids = []
    for entity in Entity.get_by_class('file', types=True):
        entity_file_ids.append(entity.id)
        if not get_file_path(entity):
            tabs['missing_files'].table.rows.append([
                link(entity),
                link(entity.class_),
                link(entity.standard_type), entity.class_.label,
                format_date(entity.created),
                format_date(entity.modified), entity.description
            ])

    # Orphaned files with no corresponding entity
    for file in app.config['UPLOAD_DIR'].iterdir():
        if file.name != '.gitignore' \
                and os.path.isfile(file) \
                and int(file.stem) not in entity_file_ids:
            tabs['orphaned_files'].table.rows.append([
                file.stem,
                convert_size(file.stat().st_size),
                format_date(
                    datetime.datetime.utcfromtimestamp(file.stat().st_ctime)),
                file.suffix,
                link(_('download'), url_for('download_file',
                                            filename=file.name)),
                delete_link(file.name,
                            url_for('admin_file_delete', filename=file.name))
            ])

    for tab in tabs.values():
        tab.buttons = [manual('admin/data_integrity_checks')]
        if not tab.table.rows:
            tab.content = _('Congratulations, everything looks fine!')
    if tabs['orphaned_files'].table.rows and is_authorized('admin'):
        text = uc_first(_('delete all files without corresponding entities?'))
        tabs['orphaned_files'].buttons.append(
            button(_('delete all files'),
                   url_for('admin_file_delete', filename='all'),
                   onclick=f"return confirm('{text}')"))
    return render_template(
        'tabs.html',
        tabs=tabs,
        title=_('admin'),
        crumbs=[[_('admin'), f"{url_for('admin_index')}#tab-data"],
                _('orphans')])
Exemplo n.º 22
0
def admin_delete_single_type_duplicate(entity_id: int,
                                       type_id: int) -> Response:
    Type.remove_by_entity_and_type(entity_id, type_id)
    flash(_('link removed'), 'info')
    return redirect(url_for('admin_check_link_duplicates'))
Exemplo n.º 23
0
 def prepare_feature_types() -> None:
     for category_id in Type.get_types('Features for sexing'):
         for id_ in g.types[category_id].subs:
             SexEstimation.features[g.types[id_].name]['id'] = \
                 g.types[id_].id
Exemplo n.º 24
0
    def test_involvement(self) -> None:
        with app.app_context():
            rv: Any = self.app.post(url_for('insert', class_='acquisition'),
                                    data={
                                        'name': 'Event Horizon',
                                        'begin_year_from': '949',
                                        'begin_month_from': '10',
                                        'begin_day_from': '8',
                                        'end_year_from': '1951',
                                        self.precision_geonames: '',
                                        self.precision_wikidata: ''
                                    })
            event_id = int(rv.location.split('/')[-1])
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                actor = Entity.insert('person', 'Captain Miller')
                involvement = Type.get_hierarchy('Involvement')

            # Add involvement
            rv = self.app.get(url_for('involvement_insert',
                                      origin_id=actor.id))
            assert b'Involvement' in rv.data
            rv = self.app.post(url_for('involvement_insert',
                                       origin_id=actor.id),
                               data={
                                   'event': str([event_id]),
                                   'activity': 'P11',
                                   'begin_year_from': '950',
                                   'end_year_from': '1950',
                                   involvement.id: involvement.id
                               },
                               follow_redirects=True)
            assert b'Event Horizon' in rv.data
            rv = self.app.post(url_for('involvement_insert',
                                       origin_id=event_id),
                               data={
                                   'actor': str([actor.id]),
                                   'continue_': 'yes',
                                   'activity': 'P22'
                               },
                               follow_redirects=True)
            assert b'Event Horizon' in rv.data
            rv = self.app.get(url_for('view', id_=event_id))
            assert b'Event Horizon' in rv.data
            rv = self.app.get(url_for('view', id_=actor.id))
            assert b'Appears first' in rv.data

            # Update involvement
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                link_id = Link.get_links(event_id, 'P22')[0].id
            rv = self.app.get(
                url_for('link_update', id_=link_id, origin_id=event_id))
            assert b'Captain' in rv.data
            rv = self.app.post(url_for('link_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
            rv = self.app.get(url_for('view', id_=actor.id))
            assert b'Appears first' in rv.data
            rv = self.app.get(url_for('view', id_=event_id))
            assert b'Infinite Space - Infinite Terror' in rv.data
Exemplo n.º 25
0
    def test_hierarchy(self) -> None:
        with app.app_context():
            # Custom types
            data = {
                'name': 'Geronimo',
                'classes':
                    ['file', 'group', 'move', 'person', 'place', 'source'],
                'multiple': True,
                'description': 'Very important!'}
            rv: Any = self.app.post(
                url_for('hierarchy_insert', category='custom'),
                follow_redirects=True,
                data=data)
            assert b'An entry has been created' in rv.data
            rv = self.app.post(
                url_for('hierarchy_insert', category='custom'),
                follow_redirects=True,
                data=data)
            assert b'The name is already in use' in rv.data
            with app.test_request_context():
                hierarchy = Type.get_hierarchy('Geronimo')
            rv = self.app.get(url_for('hierarchy_update', id_=hierarchy.id))
            assert b'Geronimo' in rv.data
            data['classes'] = ['acquisition']
            rv = self.app.post(
                url_for('hierarchy_update', id_=hierarchy.id),
                data=data,
                follow_redirects=True)
            assert b'Changes have been saved.' in rv.data

            rv = self.app.get(url_for('hierarchy_insert', category='custom'))
            assert b'+ Custom' in rv.data

            data = {'name': 'My secret type', 'description': 'Very important!'}
            rv = self.app.post(
                url_for('insert', class_='type', origin_id=hierarchy.id),
                data=data)
            type_id = rv.location.split('/')[-1]
            rv = self.app.get(
                url_for('remove_class', id_=hierarchy.id, class_name='person'),
                follow_redirects=True)
            assert b'Changes have been saved.' in rv.data
            rv = self.app.get(
                url_for('type_delete', id_=type_id),
                follow_redirects=True)
            assert b'deleted' in rv.data

            rv = self.app.post(
                url_for('hierarchy_update', id_=hierarchy.id),
                data={'name': 'Actor actor relation'},
                follow_redirects=True)
            assert b'The name is already in use' in rv.data
            rv = self.app.post(
                url_for('hierarchy_delete', id_=hierarchy.id),
                follow_redirects=True)
            assert b'deleted' in rv.data

            # Value types
            rv = self.app.get(url_for('hierarchy_insert', category='value'))
            assert b'+ Value' in rv.data
            rv = self.app.post(
                url_for('hierarchy_insert', category='value'),
                follow_redirects=True,
                data={
                    'name': 'A valued value',
                    'classes': ['file'],
                    'description': ''})
            assert b'An entry has been created' in rv.data
            with app.test_request_context():
                value_type = Type.get_hierarchy('A valued value')
            rv = self.app.get(url_for('hierarchy_update', id_=value_type.id))
            assert b'valued' in rv.data

            # Test checks
            relation_type = Type.get_hierarchy('Actor actor relation')
            rv = self.app.get(
                url_for('hierarchy_update', id_=relation_type.id),
                follow_redirects=True)
            assert b'Forbidden' in rv.data
            rv = self.app.get(
                url_for('hierarchy_delete', id_=relation_type.id),
                follow_redirects=True)
            assert b'Forbidden' in rv.data
Exemplo n.º 26
0
    def test_relation(self) -> None:
        with app.app_context():
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                actor = Entity.insert('person', 'Connor MacLeod')
                related = Entity.insert('person', 'The Kurgan')

            # Add relationship
            rv = self.app.get(url_for('relation_insert', origin_id=actor.id))
            assert b'Actor actor relation' in rv.data
            relation_id = Type.get_hierarchy('Actor actor relation').id
            relation_sub_id = g.types[relation_id].subs[0]
            relation_sub_id2 = g.types[relation_id].subs[1]
            data = {
                'actor': str([related.id]),
                relation_id: relation_sub_id,
                'inverse': None,
                'begin_year_from': '-1949',
                'begin_month_from': '10',
                'begin_day_from': '8',
                'begin_year_to': '-1948',
                'end_year_from': '2049',
                'end_year_to': '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('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('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"link to itself" in rv.data

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

            # Update relationship
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                link_id = Link.get_links(actor.id, 'OA7')[0].id
                link_id2 = Link.get_links(actor.id, 'OA7', True)[0].id

            rv = self.app.post(
                url_for('type_move_entities', id_=relation_sub_id),
                follow_redirects=True,
                data={
                    relation_id: relation_sub_id2,
                    'selection': [link_id],
                    'checkbox_values': str([link_id])})
            assert b'Entities were updated' in rv.data
            rv = self.app.post(
                url_for('type_move_entities', id_=relation_sub_id2),
                data={
                    relation_id: '',
                    'selection': [link_id],
                    'checkbox_values': str([link_id])},
                follow_redirects=True)
            assert b'Entities were updated' in rv.data

            rv = self.app.get(
                url_for('link_update', id_=link_id, origin_id=related.id))
            assert b'Connor' in rv.data
            rv = self.app.post(
                url_for('link_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('link_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
Exemplo n.º 27
0
    def get_all(objects: Optional[list[Entity]] = None,
                structure: Optional[dict[str, Any]] = None) -> dict[str, Any]:

        if not objects:
            objects = []
        all_: dict[str, list[Any]] = {
            'point': [],
            'linestring': [],
            'polygon': []
        }
        extra: dict[str, list[Any]] = {
            'supers': [],
            'subs': [],
            'siblings': []
        }
        selected: dict[str, list[Any]] = {
            'point': [],
            'linestring': [],
            'polygon': [],
            'polygon_point': []
        }

        # Include GIS of subunits which would be otherwise omitted
        subunit_ids = [
            subunit.id for subunit in structure['subunits']] \
            if structure else []
        sibling_ids = [
            sibling.id for sibling in structure['siblings']] \
            if structure else []
        extra_ids = [0]
        if structure:
            extra_ids = [
                objects[0].id if objects else 0] \
                + [structure['super_id']] \
                + subunit_ids \
                + sibling_ids
        object_ids = [x.id for x in objects] if objects else []

        for shape in ['point', 'polygon', 'linestring']:
            place_root = Type.get_hierarchy('Place')
            for row in Db.get_by_shape(shape, extra_ids):
                description = row['description'].replace('"', '\"') \
                    if row['description'] else ''
                object_desc = row['object_desc'].replace('"', '\"') \
                    if row['object_desc'] else ''
                item = {
                    'type': 'Feature',
                    'geometry': json.loads(row['geojson']),
                    'properties': {
                        'objectId': row['object_id'],
                        'objectName': row['object_name'].replace('"', '\"'),
                        'objectDescription': object_desc,
                        'id': row['id'],
                        'name':
                        row['name'].replace('"', '\"') if row['name'] else '',
                        'description': description,
                        'shapeType': row['type']
                    }
                }
                if 'types' in row and row['types']:
                    type_ids = ast.literal_eval(f"[{row['types']}]")
                    for type_id in list(set(type_ids)):
                        type_ = g.types[type_id]
                        if type_.root and type_.root[0] == place_root.id:
                            item['properties']['objectType'] = \
                                type_.name.replace('"', '\"')
                            break
                if structure and row['object_id'] == structure['super_id']:
                    extra['supers'].append(item)
                elif row['object_id'] in object_ids:
                    selected[shape].append(item)
                elif row['object_id'] in subunit_ids:  # pragma no cover
                    extra['subs'].append(item)
                elif row['object_id'] in sibling_ids:  # pragma no cover
                    extra['siblings'].append(item)
                else:
                    all_[shape].append(item)
                if 'polygon_point' in row:
                    polygon_point_item = dict(item)  # Make a copy
                    polygon_point_item['geometry'] = json.loads(
                        row['polygon_point'])
                    if row['object_id'] in object_ids:
                        selected['polygon_point'].append(polygon_point_item)
                    elif row['object_id'] and structure and \
                            row['object_id'] == structure['super_id']:
                        extra['supers'].append(polygon_point_item)
                    elif row['object_id'] in subunit_ids:  # pragma no cover
                        extra['subs'].append(polygon_point_item)
                    elif row['object_id'] in sibling_ids:  # pragma no cover
                        extra['siblings'].append(polygon_point_item)
                    else:
                        all_['point'].append(polygon_point_item)
        return {
            'gisPointAll':
            json.dumps(all_['point']),
            'gisPointSelected':
            json.dumps(selected['point']),
            'gisPointSupers':
            json.dumps(extra['supers']),
            'gisPointSubs':
            json.dumps(extra['subs']),
            'gisPointSibling':
            json.dumps(extra['siblings']),
            'gisLineAll':
            json.dumps(all_['linestring']),
            'gisLineSelected':
            json.dumps(selected['linestring']),
            'gisPolygonAll':
            json.dumps(all_['polygon']),
            'gisPolygonSelected':
            json.dumps(selected['polygon']),
            'gisPolygonPointSelected':
            json.dumps(selected['polygon_point']),
            'gisAllSelected':
            json.dumps(selected['polygon'] + selected['linestring'] +
                       selected['point'])
        }
Exemplo n.º 28
0
def add_fields(form: Any, class_: str, code: Union[str, None],
               entity: Union[Entity, Link, ReferenceSystem, Type,
                             None], origin: Union[Entity, Type, None]) -> None:
    if class_ == 'actor_actor_relation':
        setattr(form, 'inverse', BooleanField(_('inverse')))
        if not entity:
            setattr(form, 'actor',
                    TableMultiField(_('actor'), [InputRequired()]))
            setattr(form, 'relation_origin_id', HiddenField())
    elif class_ == 'artifact':
        setattr(form, 'actor', TableField(_('owned by')))
    elif class_ in view_class_mapping['event']:
        setattr(form, 'event_id', HiddenField())
        setattr(form, 'event', TableField(_('sub event of')))
        setattr(form, 'event_preceding', TableField(_('preceding event')))
        if class_ in ['activity', 'acquisition', 'production']:
            setattr(form, 'place', TableField(_('location')))
        if class_ == 'acquisition':
            setattr(form, 'given_place', TableMultiField(_('given place')))
        elif class_ == 'move':
            setattr(form, 'place_from', TableField(_('from')))
            setattr(form, 'place_to', TableField(_('to')))
            setattr(form, 'artifact', TableMultiField())
            setattr(form, 'person', TableMultiField())
        elif class_ == 'production':
            setattr(form, 'artifact', TableMultiField())
    elif class_ == 'file' and not entity:
        setattr(form, 'file', MultipleFileField(_('file'), [InputRequired()]))
        if origin and origin.class_.view == 'reference':
            setattr(form, 'page', StringField())
    elif class_ == 'group':
        setattr(form, 'residence', TableField(_('residence')))
        setattr(form, 'begins_in', TableField(_('begins in')))
        setattr(form, 'ends_in', TableField(_('ends in')))
    elif class_ == 'hierarchy':
        if code == 'custom' or (entity and isinstance(entity, Type)
                                and entity.category != 'value'):
            setattr(
                form, 'multiple',
                BooleanField(_('multiple'),
                             description=_('tooltip hierarchy multiple')))
        setattr(
            form, 'classes',
            SelectMultipleField(_('classes'),
                                render_kw={'disabled': True},
                                description=_('tooltip hierarchy forms'),
                                choices=[],
                                option_widget=widgets.CheckboxInput(),
                                widget=widgets.ListWidget(prefix_label=False)))
    elif class_ == 'involvement':
        if not entity and origin:
            involved_with = 'actor' \
                if origin.class_.view == 'event' else 'event'
            setattr(form, involved_with,
                    TableMultiField(_(involved_with), [InputRequired()]))
        setattr(form, 'activity', SelectField(_('activity')))
    elif class_ == 'actor_function' and not entity:
        setattr(form, 'member_origin_id', HiddenField())
        setattr(form, 'actor' if code == 'member' else 'group',
                TableMultiField(_('actor'), [InputRequired()]))
    elif class_ in g.view_class_mapping['type']:
        setattr(form, 'is_type_form', HiddenField())
        type_ = entity if entity else origin
        if isinstance(type_, Type):
            root = g.types[type_.root[0]] if type_.root else type_
            setattr(form, str(root.id), TreeField(str(root.id)))
            if root.directional:
                setattr(form, 'name_inverse', StringField(_('inverse')))
    elif class_ == 'person':
        setattr(form, 'residence', TableField(_('residence')))
        setattr(form, 'begins_in', TableField(_('born in')))
        setattr(form, 'ends_in', TableField(_('died in')))
    elif class_ == 'reference_system':
        setattr(form, 'website_url',
                StringField(_('website URL'),
                            [OptionalValidator(), URL()]))
        setattr(form, 'resolver_url',
                StringField(_('resolver URL'),
                            [OptionalValidator(), URL()]))
        setattr(form, 'placeholder', StringField(_('example ID')))
        precision_id = str(Type.get_hierarchy('External reference match').id)
        setattr(form, precision_id, TreeField(precision_id))
        if choices := ReferenceSystem.get_class_choices(
                entity):  # type: ignore
            setattr(
                form, 'classes',
                SelectMultipleField(
                    _('classes'),
                    render_kw={'disabled': True},
                    choices=choices,
                    option_widget=widgets.CheckboxInput(),
                    widget=widgets.ListWidget(prefix_label=False)))
Exemplo n.º 29
0
    def test_image(self) -> None:
        app.config['IMAGE_SIZE']['tmp'] = '1'
        with app.app_context():
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                place = insert_entity('Nostromos',
                                      'place',
                                      description='That is the Nostromos')
                logo = \
                    pathlib.Path(app.root_path) \
                    / 'static' / 'images' / 'layout' / 'logo.png'

            # Resizing through UI insert
            with open(logo, 'rb') as img:
                rv = self.app.post(url_for('insert',
                                           class_='file',
                                           origin_id=place.id),
                                   data={
                                       'name': 'OpenAtlas logo',
                                       'file': img
                                   },
                                   follow_redirects=True)
            assert b'An entry has been created' in rv.data

            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                files = Entity.get_by_class('file')
                file_id = files[0].id

            # Set and unset as main image
            self.app.get(url_for('set_profile_image',
                                 id_=file_id,
                                 origin_id=place.id),
                         follow_redirects=True)

            # Delete through UI
            rv = self.app.get(url_for('index', view='file', delete_id=file_id))
            assert b'The entry has been deleted' in rv.data

            # Create entities for file
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                file_pathless = insert_entity('Pathless_File', 'file')

                file = insert_entity('Test_File', 'file')
                file.link('P2', g.types[Type.get_hierarchy('License').subs[0]])
                file_name = f'{file.id}.jpeg'
                src_png = \
                    pathlib.Path(app.root_path) \
                    / 'static' / 'images' / 'layout' / 'logo.png'
                dst_png = \
                    pathlib.Path(app.config['UPLOAD_DIR'] / file_name)
                copyfile(src_png, dst_png)

                file2 = insert_entity('Test_File2', 'file')
                file2.link('P2',
                           g.types[Type.get_hierarchy('License').subs[0]])
                file2_name = f'{file2.id}.jpeg'
                src2_png = \
                    pathlib.Path(app.root_path) \
                    / 'static' / 'images' / 'layout' / 'logo.png'
                dst2_png = pathlib.Path(app.config['UPLOAD_DIR'] / file2_name)
                copyfile(src2_png, dst2_png)

                file_py = insert_entity('Test_Py', 'file')
                file_name_py = f'{file_py.id}.py'
                src_py = pathlib.Path(app.root_path) / 'views' / 'index.py'
                dst_py = pathlib.Path(app.config['UPLOAD_DIR'] / file_name_py)
                copyfile(src_py, dst_py)

                # Exception
                safe_resize_image(file2.id, '.png', size="???")
                display_profile_image(file_pathless)

            # Resizing images (don't change order!)
            rv = self.app.get(url_for('view', id_=file.id))
            assert b'Test_File' in rv.data
            rv = self.app.get(url_for('view', id_=file_py.id))
            assert b'No preview available' in rv.data
            rv = self.app.get(url_for('view', id_=file_pathless.id))
            assert b'Missing file' in rv.data
            rv = self.app.get(url_for('index', view='file'))
            assert b'Test_File' in rv.data

            # Display file
            rv = self.app.get(url_for('display_file', filename=file_name))
            assert b'\xff' in rv.data
            rv = self.app.get(
                url_for('display_file',
                        filename=file_name,
                        size=app.config['IMAGE_SIZE']['thumbnail']))
            assert b'\xff' in rv.data
            rv = self.app.get(
                url_for('display_file',
                        filename=file_name,
                        size=app.config['IMAGE_SIZE']['table']))
            assert b'\xff' in rv.data
            rv = self.app.get(
                url_for('display_file',
                        filename=file_name_py,
                        size=app.config['IMAGE_SIZE']['table']))
            assert b'404' in rv.data

            # Make directory if not exist
            rv = self.app.get(url_for('view', id_=file.id))
            assert b'Test_File' in rv.data

            # Exception
            app.config['IMAGE_SIZE']['tmp'] = '<'
            rv = self.app.get(url_for('view', id_=file.id))
            assert b'Test_File' in rv.data
            app.config['IMAGE_SIZE']['tmp'] = '1'

            rv = self.app.get(url_for('admin_resize_images'),
                              follow_redirects=True)
            assert b'Images were created' in rv.data
            rv = self.app.get(url_for('admin_delete_orphaned_resized_images'),
                              follow_redirects=True)
            assert b'Resized orphaned images were deleted' in rv.data

            rv = self.app.get(url_for('index', view='file', delete_id=file.id))
            assert b'The entry has been deleted' in rv.data
            rv = self.app.get(url_for('index', view='file',
                                      delete_id=file2.id))
            assert b'The entry has been deleted' in rv.data

            shutil.rmtree(
                pathlib.Path(app.config['RESIZED_IMAGES'] /
                             app.config['IMAGE_SIZE']['tmp']))

            dst_py.unlink()
            del app.config['IMAGE_SIZE']['tmp']
Exemplo n.º 30
0
    def test_event(self) -> None:
        with app.app_context():
            # Create entities for event
            place_name = 'Lewis and Clark'
            rv: Any = self.app.post(url_for('insert', class_='place'),
                                    data={
                                        'name': place_name,
                                        self.precision_geonames: '',
                                        self.precision_wikidata: ''
                                    })
            residence_id = rv.location.split('/')[-1]
            actor_name = 'Captain Miller'
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                actor = Entity.insert('person', actor_name)
                file = Entity.insert('file', 'X-Files')
                source = Entity.insert('source', 'Necronomicon')
                carrier = Entity.insert('artifact', 'Artifact')
                reference = Entity.insert('external_reference',
                                          'https://openatlas.eu')

            # Insert
            rv = self.app.get(url_for('insert', class_='activity'))
            assert b'+ Activity' in rv.data
            data = {
                'name': 'Event Horizon',
                'place': residence_id,
                self.precision_wikidata: ''
            }
            rv = self.app.post(url_for('insert',
                                       class_='activity',
                                       origin_id=reference.id),
                               data=data,
                               follow_redirects=True)
            assert bytes('Event Horizon', 'utf-8') in rv.data
            with app.test_request_context():
                app.preprocess_request()  # type: ignore
                activity_id = Entity.get_by_view('event')[0].id
            self.app.post(url_for('insert',
                                  class_='activity',
                                  origin_id=actor.id),
                          data=data)
            self.app.post(url_for('insert',
                                  class_='activity',
                                  origin_id=file.id),
                          data=data)
            self.app.post(url_for('insert',
                                  class_='activity',
                                  origin_id=source.id),
                          data=data)
            rv = self.app.get(
                url_for('insert', class_='activity', origin_id=residence_id))
            assert b'Location' in rv.data
            rv = self.app.get(
                url_for('insert', class_='move', origin_id=residence_id))
            assert b'Location' not in rv.data

            # Acquisition
            event_name2 = 'Second event'
            wikidata = \
                f"reference_system_id_" \
                f"{ReferenceSystem.get_by_name('Wikidata').id}"
            precision = Type.get_hierarchy('External reference match').subs[0]
            rv = self.app.post(url_for('insert', class_='acquisition'),
                               data={
                                   'name': event_name2,
                                   'given_place': [residence_id],
                                   'place': residence_id,
                                   'event': activity_id,
                                   'begin_year_from': '1949',
                                   'begin_month_from': '10',
                                   'begin_day_from': '8',
                                   'end_year_from': '1951',
                                   wikidata: 'Q123',
                                   self.precision_wikidata: precision
                               })
            event_id = rv.location.split('/')[-1]
            rv = self.app.get(url_for('view', id_=event_id))
            assert b'Event Horizon' in rv.data

            # Move
            rv = self.app.post(url_for('insert', class_='move'),
                               data={
                                   'name': 'Keep it moving',
                                   'place_to': residence_id,
                                   'place_from': residence_id,
                                   'artifact': carrier.id,
                                   'person': actor.id,
                                   self.precision_wikidata: ''
                               })
            move_id = rv.location.split('/')[-1]
            rv = self.app.get(url_for('view', id_=move_id))
            assert b'Keep it moving' in rv.data
            rv = self.app.get(url_for('view', id_=carrier.id))
            assert b'Keep it moving' in rv.data
            rv = self.app.get(url_for('update', id_=move_id))
            assert b'Keep it moving' in rv.data

            # Production
            rv = self.app.post(url_for('insert', class_='production'),
                               data={
                                   'name': 'A very productive event',
                                   'artifact': carrier.id,
                                   self.precision_wikidata: ''
                               })
            production_id = rv.location.split('/')[-1]
            rv = self.app.get(url_for('view', id_=production_id))
            assert b'Artifact' in rv.data
            rv = self.app.get(url_for('view', id_=carrier.id))
            assert b'A very productive event' in rv.data
            rv = self.app.get(url_for('update', id_=production_id))
            assert b'A very productive event' in rv.data

            # Add another event and test if events are seen at place
            event_name3 = 'Third event'
            self.app.post(url_for('insert', class_='acquisition'),
                          data={
                              'name': event_name3,
                              'given_place': [residence_id],
                              self.precision_geonames: '',
                              self.precision_wikidata: ''
                          })
            rv = self.app.get(url_for('view', id_=residence_id))
            assert bytes(place_name, 'utf-8') in rv.data
            rv = self.app.get(url_for('view', id_=actor.id))
            assert bytes(actor_name, 'utf-8') in rv.data
            rv = self.app.post(url_for('insert', class_='acquisition'),
                               follow_redirects=True,
                               data={
                                   'name': 'Event Horizon',
                                   'continue_': 'yes',
                                   self.precision_geonames: '',
                                   self.precision_wikidata: ''
                               })
            assert b'An entry has been created' in rv.data
            rv = self.app.get(url_for('index', view='event'))
            assert b'Event' in rv.data
            self.app.get(url_for('view', id_=activity_id))

            # Add to event
            rv = self.app.get(url_for('entity_add_file', id_=event_id))
            assert b'Link file' in rv.data
            rv = self.app.post(url_for('entity_add_file', id_=event_id),
                               data={'checkbox_values': str([file.id])},
                               follow_redirects=True)
            assert b'X-Files' in rv.data

            rv = self.app.get(url_for('entity_add_reference', id_=event_id))
            assert b'Link reference' in rv.data
            rv = self.app.post(url_for('entity_add_reference', id_=event_id),
                               data={
                                   'reference': reference.id,
                                   'page': '777'
                               },
                               follow_redirects=True)
            assert b'777' in rv.data

            # Update
            rv = self.app.get(url_for('update', id_=activity_id))
            assert b'Event Horizon' in rv.data
            rv = self.app.get(url_for('update', id_=event_id))
            assert b'Event Horizon' in rv.data
            data['name'] = 'Event updated'
            rv = self.app.post(url_for('update', id_=event_id),
                               data=data,
                               follow_redirects=True)
            assert b'Changes have been saved' in rv.data

            # Test super event validation
            rv = self.app.post(url_for('update', id_=event_id),
                               data={
                                   'name': 'Event',
                                   'event': event_id,
                                   'event_id': event_id
                               },
                               follow_redirects=True)
            assert b'Self as super not allowed' in rv.data

            # Preceding event
            rv = self.app.post(url_for('update', id_=event_id),
                               data={
                                   'name': 'Event',
                                   'event_preceding': event_id,
                                   'event_id': event_id
                               },
                               follow_redirects=True)
            assert b'Self as preceding not allowed' in rv.data
            rv = self.app.post(url_for('update', id_=event_id),
                               data={
                                   'name': 'Event with preceding',
                                   'event_preceding': activity_id,
                                   'event_id': event_id
                               },
                               follow_redirects=True)
            assert b'Event with preceding' in rv.data
            rv = self.app.get(url_for('view', id_=activity_id))
            assert b'Event with preceding' in rv.data

            # Delete
            rv = self.app.get(
                url_for('index', view='event', delete_id=event_id))
            assert b'The entry has been deleted.' in rv.data