Skip to content

Commit 7463aab

Browse files
Merge branch 'refs/heads/develop' into feature/femcare-import
2 parents db97513 + b07d1d8 commit 7463aab

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+999
-1181
lines changed

config/default.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from config.database_versions import DATABASE_VERSIONS
77

8-
VERSION = '9.0.0'
8+
VERSION = '9.1.0'
99
DATABASE_VERSION = DATABASE_VERSIONS[0]
1010
DEMO_MODE = False # If activated some options are disabled, login is prefilled
1111
DEBUG = False

config/model/README.md

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,72 @@
11
# Model configuration
2-
In **config/model** are the configuration files which are responsible for
3-
model relations, display, forms and similar. The main motivation for this
4-
approach is to speed up development and make it easier to understand the
5-
system.
2+
3+
Within the OpenAtlas source code configuration files, which determine model
4+
relations, display, forms and the like, can be found in **config/model**.
5+
The main motivation for this approach is to speed up development and make
6+
it easier to understand the system.
67

78
Changes can be made to test different setups, but we strongly advice against
89
implementing changes for productive environments because:
910

10-
* There may be conflicts with future OpenAtlas versions, especially because
11-
this approach is relatively new and will be subject to changes.
11+
* There may be conflicts with future OpenAtlas versions, as this approach is
12+
relatively new and will be subject to changes.
1213
* Currently, there are no check or validation functions for the configuration
13-
* Even if changes appear to work, they might cause unwanted
14-
side effects in the application, API or presentation sites.
14+
* Even if changes appear to work, they might cause unwanted side effects in
15+
the application, API or presentation sites.
1516

16-
A better approach would be to test needed changes and then tell us about
17-
it. In case we implement suggested changes, it would mitigate the
18-
issues mentioned above.
17+
A better approach would be to test needed changes and then tell us about it.
18+
In case we implement suggested changes, it would mitigate the issues mentioned
19+
above.
1920

2021
# Functionality
21-
With changes in the config files it is possible to:
22-
* Add, change or remove entity classes and their relations
23-
* Determine modes of linking, e.g. if relations are edited directly at an
24-
entity form or via tabs
22+
23+
Changes in the config files allow you to:
24+
25+
* Add, change, or remove entity classes and their relations
2526
* Change display details like labels and the order of shown items, e.g. tabs
2627

2728
# Limitations
28-
* It is not possible to add new classes via the config alone. This would also
29-
require database adaptions.
30-
* Although it is possible to define none CIDOC conform relations they will fail
31-
because of additional checks in the user interface.
29+
30+
* It is not possible to add new classes via the config alone, as this requires
31+
database adaptations. * Non-CIDOC-conformant relations can be defined in the
32+
file, but they will fail because of additional user-interface checks.
3233

3334
# File structure
35+
3436
* **class_groups.py** - configuration for grouping classes, e.g. person and
3537
group will be displayed together in "actor" sections at overviews
3638
* **model.py** - used for class instantiation
3739
* **classes** folder - detailed configuration of individual OpenAtlas classes
3840

39-
# Class configuration structure
41+
# **Class configuration structure**
42+
4043
Description of the structure for classes used in the classes directory.
44+
4145
* **label** - optional (default = class name)
4246
* **attributes**
4347
* **values**: name, alias, dates, location, description
4448
* **options**: label, required, annotated (only for description)
4549
* **relations** - the order affects display of entity views and forms
4650
* **label** - optional (default = relation name)
4751
* **classes** - a list of related OpenAtlas classes
48-
* **property** - the CIDOC property used to link them
52+
* **property** - the CIDOC property used to link classes
4953
* **inverse** - link direction (default = False)
50-
* **required** - if possible to remove (default = False)
54+
* **required** - if link is required (default = False)
5155
* **multiple** - if multiple connections are possible (default = False)
5256
* **mode**
5357
* **direct** - editable at the entity form
5458
* **tab** - editable via tabs (default)
55-
* **add_dynamic** - if types can be added dynamically (default = False)
59+
* **add_dynamic** - determines if types can be added dynamically
60+
(default = False)
5661
* **type** - special case to add a type to the link, e.g. involvement
5762
* **additional_fields** - special cases to add link information
5863
* **dates**
5964
* **description**
6065
* **page** - like description, used for references
6166
* **tooltip** - shown in entity form if mode is direct
6267
* **tab** - display options if shown via tabs
63-
* **columns** - columns shown for related entities,
64-
optional (default = standard columns)
68+
* **columns** - columns shown for related entities, optional
69+
(default = standard columns)
6570
* **buttons**
6671
* **link** - link to existing entities
6772
* **insert** - insert a new entity and link automatically
@@ -80,13 +85,13 @@ Description of the structure for classes used in the classes directory.
8085
* **insert_continue_human_remains** - continue with entering human remains
8186
* **additional_tabs**
8287
* **note** - possibility to add notes
83-
* **person_place** - special function to show event places at an actor
84-
* **place_person** - special function to show actors of events at a place
88+
* **person_place** - show event places at an actor view
89+
* **place_person** - show involved actors of events at a place view
8590
* **additional_information** - labels can be set optionally
8691
* **file_size** - used for files
8792
* **file_extension** - used for files
88-
* **type_information** - show additional infor for types, e.g. the id for
89-
imports and if selectable
93+
* **type_information** - show additional information for types, e.g. the id
94+
for imports and if selectable
9095
* **network_color** - color of entities in the backend network visualisation
9196
* **extra**
9297
* **reference_system** - possibility to configure to add external reference

openatlas/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def get_locale() -> str:
5252
def before_request() -> Response | None:
5353
from openatlas.models.cidoc import cidoc_classes, cidoc_properties
5454
from openatlas.models.entity import Entity
55-
from openatlas.models.settings import Settings
55+
from openatlas.models.settings import get_settings
5656

5757
if request.path.startswith('/static'):
5858
return None # Avoid overheads if not using Apache with static alias
@@ -61,7 +61,7 @@ def before_request() -> Response | None:
6161
g.db = open_connection(app.config)
6262
g.db.autocommit = True
6363
g.cursor = g.db.cursor(cursor_factory=extras.DictCursor)
64-
g.settings = Settings.get_settings()
64+
g.settings = get_settings()
6565

6666
if request.path.startswith('/display'):
6767
return None # Avoid overheads for file display

openatlas/api/endpoints/content.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def get() -> tuple[Resource, int] | Response:
113113
if parser == 'yaml':
114114
data = yaml.dump(data)
115115
response = make_response(data)
116-
response.headers["Content-Disposition"] = \
117-
f"attachment; filename=openapi.{parser}"
118-
response.headers["Content-Type"] = f"application/{parser}"
116+
response.headers['Content-Disposition'] = \
117+
f'attachment; filename=openapi.{parser}'
118+
response.headers['Content-Type'] = f'application/{parser}'
119119
return response

openatlas/api/endpoints/endpoint.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
replace_empty_list_values_in_dict_with_none)
2828
from openatlas.display.table import entity_table
2929
from openatlas.models.entity import Entity, Link
30-
from openatlas.models.gis import Gis
30+
from openatlas.models.gis import get_centroids_by_entities, get_gis_by_entities
3131

3232

3333
class Endpoint:
@@ -58,11 +58,10 @@ def get_links_for_entities(self) -> None:
5858
for link_ in self.link_parser_check(inverse=True):
5959
self.entities_with_links[
6060
link_.range.id]['links_inverse'].append(link_)
61-
for id_, geom in Gis.get_by_entities(self.entities).items():
61+
for id_, geom in get_gis_by_entities(self.entities).items():
6262
self.entities_with_links[id_]['geometry'].extend(geom)
6363
if self.parser.centroid:
64-
for id_, geom in \
65-
Gis.get_centroids_by_entities(self.entities).items():
64+
for id_, geom in get_centroids_by_entities(self.entities).items():
6665
self.entities_with_links[id_]['geometry'].extend(geom)
6766

6867
def get_pagination(self) -> None:
@@ -264,8 +263,7 @@ def get_entities_formatted(self) -> None:
264263
self.formated_entities = [
265264
self.get_linked_places_entity(_id)
266265
for _id in self.entities_with_links]
267-
case _ if self.parser.format \
268-
in app.config['RDF_FORMATS']: # pragma: no cover
266+
case _ if self.parser.format in app.config['RDF_FORMATS']:
269267
license_links = get_license_ids_with_links()
270268
parsed_context = parse_loud_context()
271269
self.generator_entities = (
@@ -352,7 +350,7 @@ def get_linked_places_entity(self, _id: int) -> dict[str, Any]:
352350
links = self.entities_with_links[_id]['links']
353351
links_inverse = self.entities_with_links[_id]['links_inverse']
354352
geometry = self.entities_with_links[_id]['geometry']
355-
crm = f"crm:{entity.cidoc_class.code} {entity.cidoc_class.i18n['en']}"
353+
crm = f'crm:{entity.cidoc_class.code} {entity.cidoc_class.i18n['en']}'
356354
feature = {
357355
'@id': url_for('api.entity', id_=entity.id, _external=True),
358356
'type': 'Feature',

openatlas/api/endpoints/file.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
from openatlas.api.resources.parser import files, image
1616
from openatlas.api.resources.resolve_endpoints import download
1717
from openatlas.api.resources.templates import licensed_file_template
18-
from openatlas.api.resources.util import get_iiif_manifest_and_path, \
19-
get_license_name
18+
from openatlas.api.resources.util import (
19+
get_iiif_manifest_and_path, get_license_name)
2020
from openatlas.database.overlay import get_by_object
2121
from openatlas.display.util import (
2222
check_iiif_activation, check_iiif_file_exist, get_file_path)
@@ -42,7 +42,7 @@ def get(filename: str) -> Response:
4242
size = None
4343
if parser['image_size']:
4444
size = app.config['IMAGE_SIZE'][parser['image_size']]
45-
filepath = get_file_path(entity, size)
45+
filepath = get_file_path(entity.id, size)
4646
if not filepath:
4747
raise DisplayFileNotFoundError
4848
return send_file(filepath, as_attachment=bool(parser['download']))
@@ -60,7 +60,7 @@ def get() -> Response | tuple[Any, int]:
6060
for entity in entities:
6161
if not (license_ := get_license_name(entity)):
6262
continue
63-
if not (path := get_file_path(entity)):
63+
if not (path := get_file_path(entity.id)):
6464
continue
6565
iiif_manifest = ''
6666
if check_iiif_activation() and check_iiif_file_exist(entity.id):
@@ -118,10 +118,11 @@ def get() -> Response:
118118
def get_file_dict(
119119
entity: Entity,
120120
overlay: Optional[Overlay] = None) -> dict[str, Any]:
121-
path = get_file_path(entity.id)
121+
url = 'N/A'
122122
mime_type = None
123-
if path:
124-
mime_type, _ = mimetypes.guess_type(path) # pragma: no cover
123+
if path := get_file_path(entity.id):
124+
url = url_for('api.display', filename=path.stem, _external=True)
125+
mime_type, _ = mimetypes.guess_type(path)
125126
data = {
126127
'id': entity.id,
127128
'title': entity.name,
@@ -130,10 +131,7 @@ def get_file_dict(
130131
'licenseHolder': entity.license_holder,
131132
'publicShareable': entity.public,
132133
'mimetype': mime_type,
133-
'url': url_for(
134-
'api.display',
135-
filename=path.stem,
136-
_external=True) if path else 'N/A'}
134+
'url': url}
137135
data.update(get_iiif_manifest_and_path(entity.id))
138136
if overlay:
139137
data.update({'overlay': overlay.bounding_box})

openatlas/api/endpoints/iiif.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def build_annotation(
152152
if annotation.entity_id:
153153
entity = ApiEntity.get_by_id(annotation.entity_id)
154154
url = get_url(entity.id, parser.url)
155-
entity_link = f"<a href={url} target=_blank>{entity.name}</a>"
155+
entity_link = f'<a href={url} target=_blank>{entity.name}</a>'
156156
return {
157157
"@id": url_for(
158158
'api.iiif_annotation',
@@ -296,13 +296,13 @@ def get_metadata(entity: Entity) -> dict[str, Any]:
296296
and not check_iiif_file_exist(entity.id):
297297
raise DisplayFileNotFoundError
298298
ext = '.tiff' if g.settings['iiif_conversion'] else entity.get_file_ext()
299-
image_url = f"{g.settings['iiif_url']}{entity.id}{ext}"
299+
image_url = f'{g.settings['iiif_url']}{entity.id}{ext}'
300300

301301
try:
302302
resp = requests.get(f"{image_url}/info.json", timeout=30)
303303
resp.raise_for_status()
304-
except Exception as exc: # pragma: no cover
305-
raise IIIFMetadataNotFound(image_url) from exc
304+
except Exception as e: # pragma: no cover
305+
raise IIIFMetadataNotFound(image_url) from e
306306

307307
return {'entity': entity, 'img_url': image_url, 'img_api': resp.json()}
308308

openatlas/api/external/arche.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def is_arche_likeable_uri(uri: str) -> bool:
2727
for rule in g.arche_uri_rules:
2828
if search(rule['match'], uri):
2929
return True
30-
return False # pragma: no cover
30+
return False
3131

3232

3333
def is_valid_url(url: str) -> bool:
@@ -56,12 +56,9 @@ def create_uri(value: str | list[str]) -> list[URIRef]:
5656
return [create_single_uri(value)]
5757

5858

59-
def ensure_person_exist(
60-
graph: Graph,
61-
names: str | list[str]) -> None:
59+
def ensure_person_exist(graph: Graph, names: str | list[str]) -> None:
6260
names = names if isinstance(names, list) else [names]
6361
for name in names:
64-
6562
if not name or is_valid_url(name):
6663
continue # pragma: no cover
6764
uri = create_single_uri(name)
@@ -117,13 +114,11 @@ def ensure_entity_exist(
117114

118115
def transliterate_url(url: str) -> str:
119116
parsed = urlparse(url)
120-
path = parsed.path
121-
ascii_path = unidecode(path)
122-
ascii_path = ascii_path.replace(' ', '_')
117+
ascii_path = unidecode(parsed.path)
123118
return urlunparse((
124119
parsed.scheme,
125120
parsed.netloc,
126-
ascii_path,
121+
ascii_path.replace(' ', '_'),
127122
parsed.params,
128123
parsed.query,
129124
parsed.fragment))

openatlas/api/external/arche_class.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,13 @@ def construct(
4040
publications: list[tuple[Entity, str]],
4141
license_: str) -> 'ArcheFileMetadata':
4242
metadata = app.config['ARCHE_METADATA']
43-
part_of = "https://id.acdh.oeaw.ac.at/" \
44-
f"{metadata['topCollection'].replace(' ', '_')}"
45-
titles = [(entity.name, 'und')]
43+
part_of = 'https://id.acdh.oeaw.ac.at/' \
44+
f'{metadata['topCollection'].replace(' ', '_')}'
4645
file_info = (g.files[entity.id].suffix[1:], g.files[entity.id].name)
4746
obj = cls(
48-
uri=f"{part_of}/{type_name.replace(' ', '_')}/"
49-
f"{file_info[0]}/{file_info[1]}",
50-
titles=titles)
47+
uri=f'{part_of}/{type_name.replace(' ', '_')}/'
48+
f'{file_info[0]}/{file_info[1]}',
49+
titles=[(entity.name, 'und')])
5150
obj.depositors = metadata['depositor']
5251
obj.language = metadata['language']
5352
obj.license = license_

openatlas/api/external/gnd.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88

99

1010
def fetch_gnd(id_: str) -> dict[str, Any]:
11-
url = f'{g.gnd.resolver_url}{id_}.json'
1211
info: dict[str, str] = {}
1312
try:
1413
data = requests.get(
15-
url,
14+
f'{g.gnd.resolver_url}{id_}.json',
1615
proxies=app.config['PROXIES'],
1716
timeout=10).json()
1817
except Exception: # pragma: no cover

0 commit comments

Comments
 (0)