Coverage for archeutils/utils.py: 13%
200 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-27 11:19 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-27 11:19 +0000
1from django.conf import settings
2from rdflib import Graph, Namespace, URIRef, Literal, XSD
3from rdflib.namespace import RDF
5from webpage.metadata import PROJECT_METADATA
7ARCHE_CONST_MAPPINGS = getattr(settings, "ARCHE_CONST_MAPPINGS", False)
8ARCHE_CONST_MAPPINGS_SIMPLE = getattr(settings, "ARCHE_CONST_MAPPINGS_SIMPLE", False)
10ARCHE_LANG = getattr(settings, "ARCHE_LANG", "en")
11ARCHE_BASE_URL = getattr(
12 settings, "ARCHE_BASE_URL", "https://id.acdh.oeaw.ac.at/MYPROJECT"
13)
15ARCHE_DEFAULT_EXTENSION = getattr(settings, "ARCHE_DEFAULT_EXTENSION", "geojson")
16ARCHE_PAYLOAD_MIMETYPE = getattr(
17 settings, "ARCHE_PAYLOAD_MIMETYPE", "application/geo+json"
18)
20TOP_COL_DESC = """A geodata collection on historical political/administrative units created and collected for the HistoGIS Project.
21The region covered is Europe with a special focus on Central Europe / Austria(-Hungary) and German States, the temporal extent is from c. 1815 to c. 1919. National borders are available for the whole temporal extent and all of Europe, while lower level administrative borders (provinces, counties, etc.) are available for the focus areas.
22Data is provided in GeoJSON format following the “The Linked Places format (LPF)” recommendations. The files contain geometries, timespans as well as additional attribute data. The data is structured along three axes: Geographical / political region, contemporary administrative level and time."""
24PROJECT_DESC = """The HistoGIS project creates and publishes machine readable data about historical administrative units. Maps, either historic ones or maps displaying past (political) border lines, has been georeferenced and the actual information about the former borderlines was captured as GeoJSON together with necessary metadata like the name of the temporal spatial entity, its start and end dates, alternative names as well as potential matching Wikidata IDs.
25The project was funded by the Austrian Academy of Sciences (Innovationsfonds), run from March 2018 until October 2020 and was led by Peter Andorfer and Matthias Schlögl. The actual work on the data was done by Antonia Dückelmann, Anna Piechl and Peter Paul Marckhgott-Sanabria with support from the interns Laura Elmer and Liam Downs-Tepper.
26Besides the data the project HistoGIS comprises a web service to query the data (https://histogis.acdh.oeaw.ac.at)"""
29repo_schema = (
30 "https://raw.githubusercontent.com/acdh-oeaw/repo-schema/master/acdh-schema.owl"
31)
32acdh_ns = Namespace("https://vocabs.acdh.oeaw.ac.at/schema#")
33owl_ns = Namespace("http://www.w3.org/2002/07/owl#")
34rdfs_ns = Namespace("http://www.w3.org/2000/01/rdf-schema#")
36pandorfer = URIRef("https://d-nb.info/gnd/1043833846")
37mschloegl = URIRef("https://d-nb.info/gnd/1154715620")
38apiechl = URIRef("https://orcid.org/0000-0002-9239-5577")
39adueck = URIRef("https://orcid.org/0000-0003-3392-2610")
40pmarck = URIRef("https://orcid.org/0000-0003-1816-4823")
43def get_prop_types(repo_schema_url=repo_schema):
44 g = Graph()
45 g.parse(repo_schema, format="xml")
46 prop_types = {}
47 for s in g.subjects(RDF.type, None):
48 if s.startswith("https://vocabs.acdh"):
49 prop_name = s.split("#")[-1]
50 for range_prop in g.objects(s, rdfs_ns.range):
51 prop_types[prop_name] = range_prop.split("#")[-1]
52 return prop_types
55def serialize_project():
56 g = Graph()
57 sub = URIRef(f"{ARCHE_BASE_URL}")
58 proj_sub = URIRef(f"{ARCHE_BASE_URL}/project")
59 # HistoGIS Project
60 proj_g = Graph()
61 proj_g.add((proj_sub, RDF.type, acdh_ns.Project))
62 proj_g.add(
63 (proj_sub, acdh_ns.hasTitle, Literal("HistoGIS (Project)", lang=ARCHE_LANG))
64 )
65 proj_g.add(
66 (proj_sub, acdh_ns.hasStartDate, Literal("2018-03-01", datatype=XSD.date))
67 )
68 proj_g.add((proj_sub, acdh_ns.hasEndDate, Literal("2020-11-30", datatype=XSD.date)))
69 proj_g.add((proj_sub, acdh_ns.hasFunder, URIRef("https://id.acdh.oeaw.ac.at/oeaw")))
70 for x in [adueck, apiechl, pmarck]:
71 proj_g.add((proj_sub, acdh_ns.hasContributor, x))
72 proj_g.add((proj_sub, acdh_ns.hasPrincipalInvestigator, pandorfer))
73 proj_g.add((proj_sub, acdh_ns.hasPrincipalInvestigator, mschloegl))
74 proj_g.add((proj_sub, acdh_ns.hasRelatedCollection, sub))
75 proj_g.add(
76 (proj_sub, acdh_ns.hasDescription, Literal(f"{PROJECT_DESC}", lang=ARCHE_LANG))
77 )
78 for const in ARCHE_CONST_MAPPINGS:
79 arche_prop_domain = get_prop_types().get(const[0], "No Match")
80 if arche_prop_domain == "date":
81 proj_g.add(
82 (proj_sub, acdh_ns[const[0]], Literal(const[1], datatype=XSD.date))
83 )
84 if arche_prop_domain == "string":
85 proj_g.add(
86 (proj_sub, acdh_ns[const[0]], Literal(const[1], lang=ARCHE_LANG))
87 )
88 else:
89 proj_g.add((proj_sub, acdh_ns[const[0]], URIRef(const[1])))
90 # HistoGIS Root Collection
91 g.add((sub, RDF.type, acdh_ns.TopCollection))
92 g.add(
93 (
94 sub,
95 acdh_ns.hasPid,
96 Literal(
97 "http://hdl.handle.net/21.11115/0000-000C-E12A-7", datatype=XSD.anyURI
98 ),
99 )
100 )
101 g.add((sub, acdh_ns.hasCoverageStartDate, Literal("1512-01-01", datatype=XSD.date)))
102 g.add((sub, acdh_ns.hasCoverageEndDate, Literal("1989-12-31", datatype=XSD.date)))
103 g.add(
104 (
105 sub,
106 acdh_ns.hasTitle,
107 Literal(f"{PROJECT_METADATA['title']}", lang=ARCHE_LANG),
108 )
109 )
110 g.add(
111 (
112 sub,
113 acdh_ns.hasOaiSet,
114 URIRef("https://vocabs.acdh.oeaw.ac.at/archeoaisets/kulturpool"),
115 )
116 )
117 g.add((sub, acdh_ns.hasRelatedProject, proj_sub))
118 g.add((sub, acdh_ns.hasOwner, URIRef("https://id.acdh.oeaw.ac.at/acdh")))
119 g = g + proj_g
120 # define persons
121 g.add((pandorfer, RDF.type, acdh_ns.Person))
122 g.add((pandorfer, acdh_ns.hasTitle, Literal("Peter Andorfer", lang="de")))
124 g.add((mschloegl, RDF.type, acdh_ns.Person))
125 g.add(
126 (
127 mschloegl,
128 acdh_ns.hasIdentifier,
129 URIRef("https://id.acdh.oeaw.ac.at/mschloegl"),
130 )
131 )
132 g.add((mschloegl, acdh_ns.isMemberOf, URIRef("https://id.acdh.oeaw.ac.at/acdh")))
133 g.add((mschloegl, acdh_ns.hasTitle, Literal("Matthias Schlögl", lang="und")))
134 g.add((mschloegl, acdh_ns.hasFirstName, Literal("Matthias", lang="und")))
135 g.add((mschloegl, acdh_ns.hasLastName, Literal("Schlögl", lang="und")))
137 g.add((apiechl, RDF.type, acdh_ns.Person))
138 g.add(
139 (apiechl, acdh_ns.hasIdentifier, URIRef("https://id.acdh.oeaw.ac.at/apiechl"))
140 )
141 g.add((apiechl, acdh_ns.hasTitle, Literal("Anna Piechl", lang="und")))
142 g.add((apiechl, acdh_ns.hasLastName, Literal("Piechl", lang="und")))
143 g.add((apiechl, acdh_ns.hasFirstName, Literal("Anna", lang="und")))
144 g.add((sub, acdh_ns.hasCreator, apiechl))
145 g.add((sub, acdh_ns.hasCurator, pandorfer))
147 g.add((adueck, RDF.type, acdh_ns.Person))
148 g.add(
149 (
150 adueck,
151 acdh_ns.hasIdentifier,
152 URIRef("https://id.acdh.oeaw.ac.at/adueckelmann"),
153 )
154 )
155 g.add((adueck, acdh_ns.hasTitle, Literal("Antonia Dückelmann", lang="und")))
156 g.add((adueck, acdh_ns.hasLastName, Literal("Dückelmann", lang="und")))
157 g.add((adueck, acdh_ns.hasFirstName, Literal("Antonia", lang="und")))
158 g.add((sub, acdh_ns.hasCreator, adueck))
160 g.add((URIRef("https://orcid.org/0000-0003-4135-713X"), RDF.type, acdh_ns.Person))
161 g.add(
162 (
163 URIRef("https://orcid.org/0000-0003-4135-713X"),
164 acdh_ns.hasIdentifier,
165 URIRef("https://id.acdh.oeaw.ac.at/lelmer"),
166 )
167 )
168 g.add(
169 (
170 URIRef("https://orcid.org/0000-0003-4135-713X"),
171 acdh_ns.hasTitle,
172 Literal("Laura Elmer", lang="und"),
173 )
174 )
175 g.add(
176 (
177 URIRef("https://orcid.org/0000-0003-4135-713X"),
178 acdh_ns.hasLastName,
179 Literal("Elmer", lang="und"),
180 )
181 )
182 g.add(
183 (
184 URIRef("https://orcid.org/0000-0003-4135-713X"),
185 acdh_ns.hasFirstName,
186 Literal("Laura", lang="und"),
187 )
188 )
189 g.add(
190 (sub, acdh_ns.hasContributor, URIRef("https://orcid.org/0000-0003-4135-713X"))
191 )
193 g.add((URIRef("https://orcid.org/0000-0003-2271-8948"), RDF.type, acdh_ns.Person))
194 g.add(
195 (
196 URIRef("https://orcid.org/0000-0003-2271-8948"),
197 acdh_ns.hasIdentifier,
198 URIRef("https://id.acdh.oeaw.ac.at/ldownstepper"),
199 )
200 )
201 g.add(
202 (
203 URIRef("https://orcid.org/0000-0003-2271-8948"),
204 acdh_ns.hasTitle,
205 Literal("Liam Downs-Tepper", lang="und"),
206 )
207 )
208 g.add(
209 (
210 URIRef("https://orcid.org/0000-0003-2271-8948"),
211 acdh_ns.hasFirstName,
212 Literal("Liam", lang="und"),
213 )
214 )
215 g.add(
216 (
217 URIRef("https://orcid.org/0000-0003-2271-8948"),
218 acdh_ns.hasLastName,
219 Literal("Downs-Tepper", lang="und"),
220 )
221 )
222 g.add(
223 (sub, acdh_ns.hasContributor, URIRef("https://orcid.org/0000-0003-2271-8948"))
224 )
226 g.add((pmarck, RDF.type, acdh_ns.Person))
227 g.add(
228 (
229 pmarck,
230 acdh_ns.hasTitle,
231 Literal("Peter Paul Marckhgott-Sanabria", lang="und"),
232 )
233 )
234 g.add((pmarck, acdh_ns.hasLastName, Literal("Marckhgott-Sanabria", lang="und")))
235 g.add((pmarck, acdh_ns.hasFirstName, Literal("Peter Paul", lang="und")))
236 g.add((sub, acdh_ns.hasCreator, pmarck))
237 g.add((sub, acdh_ns.hasDescription, Literal(f"{TOP_COL_DESC}", lang=ARCHE_LANG)))
238 for const in ARCHE_CONST_MAPPINGS_SIMPLE:
239 arche_prop_domain = get_prop_types().get(const[0], "No Match")
240 if arche_prop_domain == "date":
241 g.add((sub, acdh_ns[const[0]], Literal(const[1], datatype=XSD.date)))
242 if arche_prop_domain == "string":
243 g.add((sub, acdh_ns[const[0]], Literal(const[1], lang=ARCHE_LANG)))
244 else:
245 g.add((sub, acdh_ns[const[0]], URIRef(const[1])))
246 return g
249def get_arche_id(res, id_prop="pk", arche_uri=ARCHE_BASE_URL):
250 """function to generate generic ARCHE-IDs
251 :param res: A model object
252 :param id_prop: The object's primary key property
253 :param arche_uri: A base url; should be configued in the subs settings file
254 :return: An ARCHE-ID (URI)
255 """
256 if isinstance(res, str):
257 return res
258 else:
259 app_name = res.__class__._meta.app_label.lower()
260 class_name = res.__class__.__name__.lower()
261 return "/".join([arche_uri, app_name, class_name, f"{getattr(res, id_prop)}"])
264def as_arche_graph(res):
265 g = Graph()
266 sub = URIRef(f"{ARCHE_BASE_URL}/{res.source.slug_name()}/{res.slug_name()}")
267 g.add(
268 (
269 sub,
270 acdh_ns.hasOaiSet,
271 URIRef("https://vocabs.acdh.oeaw.ac.at/archeoaisets/kulturpool"),
272 )
273 )
274 g.add((sub, acdh_ns.hasTitle, Literal(f"{res}", lang="und")))
275 alt_names = res.alt_name.replace(",", ";")
276 for x in alt_names.split(";"):
277 if x != "":
278 g.add(
279 (
280 sub,
281 acdh_ns.hasAlternativeTitle,
282 Literal(f"{x.strip()}", lang=ARCHE_LANG),
283 )
284 )
285 if res.administrative_unit.pref_label is not None or "":
286 g.add(
287 (
288 sub,
289 acdh_ns.hasSubject,
290 Literal(
291 f"{res.administrative_unit.pref_label}",
292 lang=f"{res.administrative_unit.pref_label_lang[:1]}",
293 ),
294 )
295 )
296 quote = res.source.quote
297 g.add(
298 (
299 sub,
300 acdh_ns.hasDescription,
301 Literal(
302 f"{res} in: {quote}",
303 lang=ARCHE_LANG,
304 ),
305 )
306 )
307 # create place
308 pl = Graph()
309 sub_pl = URIRef(
310 f"{ARCHE_BASE_URL}/{res.source.slug_name()}/{res.slug_name()}/place"
311 )
312 pl.add((sub_pl, RDF.type, acdh_ns.Place))
313 pl.add((sub_pl, acdh_ns.hasTitle, Literal(f"Place for {res}", lang="und")))
314 pl.add((sub_pl, acdh_ns.hasWkt, Literal(f"{res.geom.wkt}")))
315 g.add((sub, acdh_ns.hasSpatialCoverage, sub_pl))
316 g = g + pl
317 # if res.wikidata_id:
318 # g.add(
319 # (
320 # sub,
321 # SKOS.broadMatch,
322 # Literal(f"https://www.wikidata.org/entity/{res.wikidata_id}")
323 # )
324 # )
325 # g.add(
326 # (
327 # sub, acdh_ns.hasDescription,
328 # Literal(
329 # f"",
330 # lang=ARCHE_LANG
331 # )
332 # )
333 # )
334 if "Marckhgott" in quote:
335 g.add((sub, acdh_ns.hasCreator, pmarck))
336 if "Piechl" in quote:
337 g.add((sub, acdh_ns.hasCreator, apiechl))
338 if "Dückelmann" in quote:
339 g.add((sub, acdh_ns.hasCreator, adueck))
340 g.add((sub, RDF.type, acdh_ns.Resource))
341 g.add(
342 (
343 sub,
344 acdh_ns.hasNonLinkedIdentifier,
345 Literal(f"HistoGIS DB-ID {res.id}", lang=ARCHE_LANG),
346 )
347 )
348 g.add(
349 (
350 sub,
351 acdh_ns.hasNonLinkedIdentifier,
352 Literal(f"Wikidata ID: {res.wikidata_id}"),
353 )
354 )
355 col = Graph()
356 col_sub = URIRef(f"{ARCHE_BASE_URL}/{res.source.slug_name()}")
357 g.add((col_sub, RDF.type, acdh_ns.Collection))
358 g.add(
359 (
360 col_sub,
361 acdh_ns.hasDescription,
362 Literal(res.source.description, lang=ARCHE_LANG),
363 )
364 )
365 col.add((col_sub, acdh_ns.isPartOf, URIRef(f"{ARCHE_BASE_URL}")))
366 col.add(
367 (
368 col_sub,
369 acdh_ns.hasOaiSet,
370 URIRef("https://vocabs.acdh.oeaw.ac.at/archeoaisets/kulturpool"),
371 )
372 )
373 if res.source.end_date is not None:
374 col.add(
375 (
376 col_sub,
377 acdh_ns.hasCoverageEndDate,
378 Literal(res.source.end_date, datatype=XSD.date),
379 )
380 )
381 if res.source.start_date is not None:
382 col.add(
383 (
384 col_sub,
385 acdh_ns.hasCoverageStartDate,
386 Literal(res.source.start_date, datatype=XSD.date),
387 )
388 )
389 col.add((col_sub, acdh_ns.hasTitle, Literal(f"{res.source}", lang=ARCHE_LANG)))
390 g.add((sub, acdh_ns.isPartOf, col_sub))
391 if res.start_date is not None:
392 g.add(
393 (
394 sub,
395 acdh_ns.hasCoverageStartDate,
396 Literal(res.start_date, datatype=XSD.date),
397 )
398 )
399 if res.end_date is not None:
400 g.add(
401 (sub, acdh_ns.hasCoverageEndDate, Literal(res.end_date, datatype=XSD.date))
402 )
403 g.add(
404 (
405 sub,
406 acdh_ns.hasCategory,
407 URIRef("https://vocabs.acdh.oeaw.ac.at/archecategory/dataset"),
408 )
409 )
410 for const in ARCHE_CONST_MAPPINGS_SIMPLE:
411 arche_prop_domain = get_prop_types().get(const[0], "No Match")
412 if arche_prop_domain == "date":
413 col.add()
414 g.add((sub, acdh_ns[const[0]], Literal(const[1], datatype=XSD.date)))
415 col.add((col_sub, acdh_ns[const[0]], Literal(const[1], datatype=XSD.date)))
416 if arche_prop_domain == "string":
417 g.add((sub, acdh_ns[const[0]], Literal(const[1], lang=ARCHE_LANG)))
418 col.add((col_sub, acdh_ns[const[0]], Literal(const[1], lang=ARCHE_LANG)))
419 else:
420 g.add((sub, acdh_ns[const[0]], URIRef(const[1])))
421 col.add((col_sub, acdh_ns[const[0]], URIRef(const[1])))
422 g = g + col
423 return g
426def title_img():
427 g = Graph()
428 sub = URIRef(f"{ARCHE_BASE_URL}/histogis_projektlogo_black.png")
429 sandra = URIRef("https://id.acdh.oeaw.ac.at/slehecka")
430 sandra_g = Graph()
431 sandra_g.add((sandra, RDF.type, acdh_ns.Person))
432 sandra_g.add((sandra, acdh_ns.hasTitle, Literal("Sandra Lehecka", lang="und")))
433 sandra_g.add((sandra, acdh_ns.hasFirstName, Literal("Sandra", lang="und")))
434 sandra_g.add(
435 (sandra, acdh_ns.isMemberOf, URIRef("https://id.acdh.oeaw.ac.at/acdh"))
436 )
438 sandra_g.add((sandra, acdh_ns.hasLastName, Literal("Lehecka", lang="und")))
439 g.add((sub, RDF.type, acdh_ns.Resource))
440 g = g + sandra_g
441 g.add((sub, acdh_ns.hasCreator, sandra))
442 g.add((sub, acdh_ns.hasTitle, Literal("HistoGIS Title Logo", lang=ARCHE_LANG)))
443 g.add((sub, acdh_ns.isPartOf, URIRef(f"{ARCHE_BASE_URL}")))
444 g.add(
445 (
446 sub,
447 acdh_ns.hasCategory,
448 URIRef("https://vocabs.acdh.oeaw.ac.at/archecategory/image"),
449 )
450 )
451 g.add((sub, acdh_ns.isTitleImageOf, URIRef(f"{ARCHE_BASE_URL}")))
452 for const in ARCHE_CONST_MAPPINGS_SIMPLE:
453 arche_prop_domain = get_prop_types().get(const[0], "No Match")
454 if arche_prop_domain == "date":
455 g.add((sub, acdh_ns[const[0]], Literal(const[1], datatype=XSD.date)))
456 if arche_prop_domain == "string":
457 g.add((sub, acdh_ns[const[0]], Literal(const[1], lang=ARCHE_LANG)))
458 else:
459 g.add((sub, acdh_ns[const[0]], URIRef(const[1])))
461 return g