Ejemplo n.º 1
0
 def update(self, form: Optional[FlaskForm] = None) -> None:
     from openatlas.util.display import sanitize
     if form:  # e.g. imports have no forms
         self.save_nodes(form)
         if self.class_.name != 'object_location':
             self.set_dates(form)
             self.update_aliases(form)
         for field in ['name', 'description']:
             if hasattr(form, field):
                 setattr(self, field, getattr(form, field).data)
         if hasattr(form, 'name_inverse'):  # A directional node, e.g. actor actor relation
             self.name = form.name.data.replace('(', '').replace(')', '').strip()
             if form.name_inverse.data.strip():
                 inverse = form.name_inverse.data.replace('(', '').replace(')', '').strip()
                 self.name += ' (' + inverse + ')'
     if self.class_.name == 'type':
         self.name = sanitize(self.name, 'node')
     elif self.class_.name == 'object_location':
         self.name = 'Location of ' + self.name
         self.description = None
     Db.update({
         'id': self.id,
         'name': str(self.name).strip(),
         'begin_from': Date.datetime64_to_timestamp(self.begin_from),
         'begin_to': Date.datetime64_to_timestamp(self.begin_to),
         'end_from': Date.datetime64_to_timestamp(self.end_from),
         'end_to': Date.datetime64_to_timestamp(self.end_to),
         'begin_comment': str(self.begin_comment).strip() if self.begin_comment else None,
         'end_comment': str(self.end_comment).strip() if self.end_comment else None,
         'description': sanitize(self.description, 'text')})
Ejemplo n.º 2
0
 def get_by_project_id(project_id: int) -> List[Entity]:
     entities = []
     for row in Db.get_by_project_id(project_id):
         entity = Entity(row)
         entity.origin_id = ['origin_id']
         entities.append(entity)
     return entities
Ejemplo n.º 3
0
 def get_display_files() -> list[Entity]:
     entities = []
     for row in Db.get_by_class('file', types=True):
         ext = g.file_stats[row['id']]['ext'] \
             if row['id'] in g.file_stats else 'N/A'
         if ext in app.config['DISPLAY_FILE_EXTENSIONS']:
             entities.append(Entity(row))
     return entities
Ejemplo n.º 4
0
 def update_gis(self, gis_data: dict[str, Any], new: bool) -> None:
     from openatlas.models.gis import Gis
     if not self.location:
         self.location = self.get_linked_entity_safe('P53')
     if not new:
         Db.update({
             'id': self.location.id,
             'name': f'Location of {str(self.name).strip()}',
             'begin_from': None,
             'begin_to': None,
             'end_from': None,
             'end_to': None,
             'begin_comment': None,
             'end_comment': None,
             'description': None})
         Gis.delete_by_entity(self.location)
     Gis.insert(self.location, gis_data)
Ejemplo n.º 5
0
 def update_attributes(self, attributes: dict[str, Any]) -> None:
     for key, value in attributes.items():
         setattr(self, key, value)
     Db.update({
         'id': self.id,
         'name': str(self.name).strip(),
         'begin_from': datetime64_to_timestamp(self.begin_from),
         'begin_to': datetime64_to_timestamp(self.begin_to),
         'end_from': datetime64_to_timestamp(self.end_from),
         'end_to': datetime64_to_timestamp(self.end_to),
         'begin_comment':
             str(self.begin_comment).strip() if self.begin_comment else None,
         'end_comment':
             str(self.end_comment).strip() if self.end_comment else None,
         'description':
             sanitize(self.description, 'text') if self.description else None
     })
Ejemplo n.º 6
0
 def get_by_class(
         classes: Union[str, list[str]],
         types: bool = False,
         aliases: bool = False) -> list[Entity]:
     if aliases:  # For performance: check classes if they can have an alias
         aliases = False
         for class_ in classes if isinstance(classes, list) \
                 else [classes]:
             if g.classes[class_].alias_allowed:
                 aliases = True
                 break
     return [Entity(row) for row in Db.get_by_class(classes, types, aliases)]
Ejemplo n.º 7
0
 def get_by_ids(ids: Iterable[int],
                types: bool = False,
                aliases: bool = False) -> list[Entity]:
     entities = []
     for row in Db.get_by_ids(ids, types, aliases):
         if row['id'] in g.types:
             entities.append(g.types[row['id']])
         elif row['id'] in g.reference_systems:
             entities.append(g.reference_systems[row['id']])
         else:
             entities.append(Entity(row))
     return entities
Ejemplo n.º 8
0
 def insert(class_name: str, name: str, description: Optional[str] = None) -> Entity:
     from openatlas.util.display import sanitize
     if not name:  # pragma: no cover
         from openatlas import logger
         logger.log('error', 'model', 'Insert entity without name')
         abort(422)
     id_ = Db.insert({
         'name': str(name).strip(),
         'code': g.classes[class_name].cidoc_class.code,
         'system_class': class_name,
         'description': sanitize(description, 'text') if description else None})
     return Entity.get_by_id(id_)
Ejemplo n.º 9
0
 def get_by_id(id_: int,
               nodes: bool = False,
               aliases: bool = False) -> Union[Entity, Node, 'ReferenceSystem']:
     if id_ in g.nodes:
         return g.nodes[id_]
     if id_ in g.reference_systems:
         return g.reference_systems[id_]
     data = Db.get_by_id(id_, nodes, aliases)
     if not data:
         if 'activity' in request.path:
             raise AttributeError  # pragma: no cover, re-raise if user activity view
         abort(418)
     return Entity(data)
Ejemplo n.º 10
0
 def get_by_class_code(
         code: Union[str, list[str]],
         parser: dict[str, Any]) -> list[dict[str, Any]]:
     sql_parts = Filter.get_filter(
         parameters={
             'codes': tuple(code if isinstance(code, list) else [code])},
         parser=parser)
     sql = Entity.select_sql(types=True) + f"""
         WHERE cidoc_class_code IN %(codes)s {sql_parts['clause']}
         GROUP BY e.id
         ORDER BY {', '.join(parser['column'])} {parser['sort']};"""
     g.cursor.execute(sql, sql_parts['parameters'])
     return [dict(row) for row in g.cursor.fetchall()]
Ejemplo n.º 11
0
 def get_by_system_class(classes: str,
                         parser: Dict[str, Any]) -> List[Dict[str, Any]]:
     sql_parts = Filter.get_filter(parameters={
         'class':
         tuple(classes if isinstance(classes, list) else [classes])
     },
                                   parser=parser)
     sql = Entity.build_sql(nodes=True, aliases=True) + f"""
         WHERE e.system_class IN %(class)s {sql_parts['clause']}
         GROUP BY e.id
         ORDER BY {', '.join(parser['column'])} {parser['sort']};"""
     g.cursor.execute(sql, sql_parts['parameters'])
     return [dict(row) for row in g.cursor.fetchall()]
Ejemplo n.º 12
0
 def get_by_class(
         classes: Union[str, List[str]],
         nodes: bool = False,
         aliases: bool = False) -> List[Entity]:
     if aliases:  # For performance: check classes if they can have an alias
         aliases_needed = False
         for system_class in classes if isinstance(classes, list) \
                 else [classes]:
             if g.classes[system_class].alias_possible:
                 aliases_needed = True
                 break
         aliases = aliases_needed
     return [Entity(row) for row in Db.get_by_class(classes, nodes, aliases)]
Ejemplo n.º 13
0
 def get_by_system_class(classes: str, parser: Dict[str,
                                                    Any]) -> List[Entity]:
     parameters = {
         'class': tuple(classes if isinstance(classes, list) else [classes])
     }
     sql = Db.build_sql(nodes=True, aliases=True) + """
         WHERE e.system_class
         IN %(class)s {clause}
         GROUP BY e.id ORDER BY {order} {sort};""".format(
         clause=Filter.get_filter(parameters=parameters, parser=parser),
         order=', '.join(parser['column']),
         sort=parser['sort'])
     g.cursor.execute(sql, parameters)
     return [Entity(row) for row in g.cursor.fetchall()]
Ejemplo n.º 14
0
 def get_by_class_code_api(code: Union[str, List[str]],
                           parser: Dict[str, Any]) -> List[Entity]:
     parameters = {
         'codes': tuple(code if isinstance(code, list) else [code])
     }
     sql = Db.build_sql(nodes=True) + """
         WHERE class_code IN %(codes)s {clause} 
         GROUP BY e.id
         ORDER BY {order} {sort};""".format(
         clause=Filter.get_filter(parameters=parameters, parser=parser),
         order=', '.join(parser['column']),
         sort=parser['sort'])
     g.cursor.execute(sql, parameters)
     return [Entity(row) for row in g.cursor.fetchall()]
Ejemplo n.º 15
0
 def get_by_id(
         id_: int,
         types: bool = False,
         aliases: bool = False) -> Union[Entity, Type, ReferenceSystem]:
     if id_ in g.types:
         return g.types[id_]
     if id_ in g.reference_systems:
         return g.reference_systems[id_]
     data = Db.get_by_id(id_, types, aliases)
     if not data:
         if 'activity' in request.path:  # Re-raise if in user activity view
             raise AttributeError  # pragma: no cover
         abort(418)
     return Entity(data)
Ejemplo n.º 16
0
 def test_links(self) -> None:
     from openatlas.database.entity import Entity as DbEntity
     from openatlas.database.link import Link as DbLink
     with app.app_context():
         with app.test_request_context():
             app.preprocess_request()  # type: ignore
             id_ = DbEntity.insert({
                 'name': 'Invalid linked entity',
                 'openatlas_class_name': 'artifact',
                 'code': 'E13', 'description': ''})
             DbLink.insert({
                 'property_code': 'P86',
                 'domain_id': id_,
                 'range_id': id_,
                 'description': '',
                 'type_id': None})
             rv = self.app.get(url_for('admin_check_links'))
             assert b'Invalid linked entity' in rv.data
Ejemplo n.º 17
0
def search(data: dict[str, Any]) -> list[Entity]:
    if not data['term']:
        return []
    if 'person' in data['classes'] \
            or 'place' in data['classes'] \
            or 'group' in data['classes']:
        data['classes'].append('appellation')
    entities = []
    for row in Db.search(data['term'], data['classes'], data['desc'],
                         data['own'], current_user.id):
        if row['openatlas_class_name'] == 'appellation':
            entity = Link.get_linked_entity_safe(row['id'], 'P1', True)
            if entity.class_.name not in data['classes']:
                continue
        else:
            entity = Entity(row)
        if entity and check_dates(entity, data):
            entities.append(entity)
    return list({d.id: d for d in entities}.values())  # Remove duplicates
Ejemplo n.º 18
0
 def get_orphans() -> List[Entity]:
     return [Entity.get_by_id(row['id']) for row in Db.get_orphans()]
Ejemplo n.º 19
0
 def get_overview_counts() -> Dict[str, int]:
     return Db.get_overview_counts(g.class_view_mapping.keys())
Ejemplo n.º 20
0
 def get_by_cidoc_class(code: Union[str, List[str]]) -> List[Entity]:
     return [Entity(row) for row in Db.get_by_cidoc_class(code)]
Ejemplo n.º 21
0
 def get_latest(limit: int) -> List[Entity]:
     return [Entity(row) for row in Db.get_latest(g.class_view_mapping.keys(), limit)]
Ejemplo n.º 22
0
 def get_by_ids(ids: Iterable[int], nodes: bool = False) -> List[Entity]:
     return [Entity(row) for row in Db.get_by_ids(ids, nodes)]
Ejemplo n.º 23
0
 def get_circular() -> List[Entity]:  # Get entities that are linked to itself.
     return [Entity.get_by_id(row['domain_id']) for row in Db.get_circular()]
Ejemplo n.º 24
0
 def get_display_files() -> List[Entity]:
     entities = []
     for row in Db.get_by_class('file', nodes=True):
         if get_file_extension(row['id']) in app.config['DISPLAY_FILE_EXTENSIONS']:
             entities.append(Entity(row))
     return entities
Ejemplo n.º 25
0
 def get_by_class(classes: Union[str, List[str]],
                  nodes: bool = False,
                  aliases: bool = False) -> List[Entity]:
     return [Entity(row) for row in Db.get_by_class(classes, nodes, aliases)]
Ejemplo n.º 26
0
 def delete_(id_: Union[int, List[int]]) -> None:
     if not id_:
         return
     Db.delete(id_ if isinstance(id_, list) else [id_])
Ejemplo n.º 27
0
 def set_profile_image(id_: int, origin_id: int) -> None:
     Db.set_profile_image(id_, origin_id)
Ejemplo n.º 28
0
 def get_profile_image_id(self) -> Optional[int]:
     return Db.get_profile_image_id(self.id)
Ejemplo n.º 29
0
def search(form: FlaskForm) -> ValuesView[Entity]:
    if not form.term.data:
        return {}.values()
    classes = form.classes.data
    if 'person' in classes:
        classes.append('actor_appellation')
    if 'place' in classes:
        classes.append('appellation')

    # Repopulate date fields with autocompleted values
    from_date = Date.form_to_datetime64(form.begin_year.data,
                                        form.begin_month.data,
                                        form.begin_day.data)
    to_date = Date.form_to_datetime64(form.end_year.data,
                                      form.end_month.data,
                                      form.end_day.data,
                                      to_date=True)
    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])

    # Get search results
    entities = []
    for row in Db.search(form.term.data, tuple(form.classes.data),
                         form.desc.data, form.own.data, current_user.id):
        if row['system_class'] == 'actor_appellation':  # If found in actor alias
            entity = Link.get_linked_entity(row['id'], 'P131', True)
        elif row['system_class'] == 'appellation':  # If found in place alias
            entity = Link.get_linked_entity(row['id'], 'P1', True)
        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
Ejemplo n.º 30
0
 def remove_profile_image(self) -> None:
     Db.remove_profile_image(self.id)