Commit 3231bc02 authored by Günter Hipler's avatar Günter Hipler
Browse files

more facts / trying to get a better understanding

parent a17358e1
Pipeline #22817 passed with stages
in 6 minutes and 31 seconds
......@@ -80,6 +80,11 @@ class EDM {
cho.addDescription(Extractors.descriptiveNote(record))
cho.addCreationDate(Extractors.creationDate(graph)(record.obj))
Extractors
.resourceCreator(graph)(
record.value
).foreach(c => cho.addCreator(Some(c._2)))
ExtractionResult(cho)
}
......
/*
* IIIF Manifest Creator
* Copyright (C) 2020 Memobase
* Copyright (C) 2021 Memobase
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
......@@ -126,8 +126,9 @@ object Extractors {
.flatMap(obj =>
getBlankNodeContent(graph)(obj)("creationRelationHasTarget")
.flatMap(v => stringValue(v)("name")) match {
case Some(name) => Some(obj("name").str, name)
case None => None
case Some(name) =>
Some(obj.getOrElse("name", obj("type")).str, name)
case None => None
}
)
.toList
......@@ -171,17 +172,25 @@ object Extractors {
recordSet =>
getBlankNodeContent(graph)(recordSet)("heldBy")
.flatMap(v => v.get("P154").flatMap(vi => Some(vi.str))) */
val manifestId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("@id").flatMap(v => Some(s"$v/manifest"))
val digitalObjectId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("@id")
val dobjectId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("@id").flatMap(Some(_))
val recordId: JObj => Option[String] = record => stringValue(record)("@id").flatMap(Some(_))
val manifestId: JObj => Option[String] = digitalObject =>
digitalObjectId(digitalObject).flatMap(v => Some(s"$v/manifest"))
val sequenceId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("@id").flatMap(v => Some(s"$v/sequence/default"))
digitalObjectId(digitalObject).flatMap(v => Some(s"$v/sequence/default"))
val canvasId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("@id").flatMap(v => Some(s"$v/canvas/default"))
digitalObjectId(digitalObject).flatMap(v => Some(s"$v/canvas/default"))
// This is a slight concession to the fact that the locator is sent as invalid
// sftp link. The locator link can however be built easily from the digitalObject
// id, so we check only the existence of the locator property, but discard a potential
// value.
val imageResourceId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("locator")
val mimeType: JObj => Option[String] = digitalObject =>
......@@ -197,7 +206,4 @@ object Extractors {
getBlankNodeContent(graph)(record)("created").flatMap(v =>
stringValue(v)("normalizedDateValue")
)
val recordId: JObj => Option[String] = record => stringValue(record)("@id").flatMap(Some(_))
}
/*
* IIIF Manifest Creator
* Copyright (C) 2020 Memobase
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ch.memobase.edm.guenterold
import ujson.Value.{Value => JValue}
import ujson.{Arr => JArr, Obj => JObj, Str => JStr}
import scala.collection.mutable
import scala.util.Try
object Extractors {
val jsonGraph: String => Try[JValue] = jsonString =>
Try { ujson.read(jsonString).obj("@graph").arr }
private val fedoraResource =
(jsonGraph: JArr) =>
(resourceType: String) =>
Try {
jsonGraph.value.collectFirst {
case res
if (res.obj
.contains("type") && res.obj("type").str == resourceType) ||
(res.obj.contains("@type") && res
.obj("@type")
.str == resourceType) =>
res.obj.value
}.get
}
private val getBlankNodeContent = (graph: JArr) =>
(resource: mutable.LinkedHashMap[String, JValue]) =>
(property: String) =>
graph.value.collectFirst {
case res
if res.obj("@id") == resource.getOrElse(property, JStr("")) =>
res.obj.value
}
private val getBlankNodesContent = (graph: JArr) =>
(resource: mutable.LinkedHashMap[String, JValue]) =>
(property: String) =>
graph.value
.filter(res =>
res.obj("@id") == resource.getOrElse(property, JStr(""))
)
.map(_.obj.value)
val digitalObject: JArr => Try[mutable.LinkedHashMap[String, JValue]] = {
jsonGraph => fedoraResource(jsonGraph)("digitalObject")
}
val record: JArr => Try[mutable.LinkedHashMap[String, JValue]] = jsonGraph =>
fedoraResource(jsonGraph)(
"https://www.ica.org/standards/RiC/ontology#Record"
)
/*val recordSet: JArr => Try[mutable.LinkedHashMap[String, JValue]] =
jsonGraph => fedoraResource(jsonGraph)("recordSet")*/
private val stringValue = (jsonObj: JObj) =>
(valueKey: String) => jsonObj.value.get(valueKey).flatMap(v => v.strOpt)
private val numValue = (jsonObj: JObj) =>
(valueKey: String) =>
stringValue(jsonObj)(valueKey).flatMap(v => Some(v.toDouble))
private val arrayValues = (jsonObj: JObj) =>
(valueKey: String) =>
jsonObj.value.get(valueKey).flatMap(v => Some(v.arr.toList.map(_.str)))
val ricoType: JObj => Option[String] = record => stringValue(record)("type")
val title: JObj => Option[String] = record => stringValue(record)("title")
val descriptiveNote: JObj => Option[String] = record =>
stringValue(record)("descriptiveNote")
val scopeAndContent: JObj => Option[String] = record =>
stringValue(record)("scopeAndContent")
val publishedBy
: JArr => mutable.LinkedHashMap[String, JValue] => Option[String] =
graph =>
record =>
getBlankNodeContent(graph)(record)("publishedBy").flatMap(v =>
stringValue(v)("name")
)
val placeOfCapture
: JArr => mutable.LinkedHashMap[String, JValue] => Option[String] =
graph =>
record =>
getBlankNodeContent(graph)(record)("P60556").flatMap(v =>
stringValue(v)("name")
)
val spatial: JArr => mutable.LinkedHashMap[String, JValue] => Option[String] =
graph =>
record =>
getBlankNodeContent(graph)(record)("spatial").flatMap(v =>
stringValue(v)("name")
)
val hasLanguage
: JArr => mutable.LinkedHashMap[String, JValue] => Option[String] =
graph =>
record =>
getBlankNodeContent(graph)(record)("hasLanguage").flatMap(v =>
stringValue(v)("name")
)
//noinspection ScalaStyle
val resourceCreator: JArr => mutable.LinkedHashMap[String, JValue] => List[
(String, String)
] =
graph =>
record =>
getBlankNodesContent(graph)(record)(
"recordResourceOrInstantiationIsSourceOfCreationRelation"
)
.flatMap(obj =>
getBlankNodeContent(graph)(obj)("creationRelationHasTarget")
.flatMap(v => stringValue(v)("name")) match {
case Some(name) => Some(obj("name").str, name)
case None => None
}
)
.toList
val producer
: JArr => mutable.LinkedHashMap[String, JValue] => Option[String] =
graph =>
record =>
getBlankNodeContent(graph)(record)("P60441").flatMap(v =>
stringValue(v)("name")
)
val componentColor: JObj => Option[List[String]] = digitalObject =>
arrayValues(digitalObject)("componentColor")
val dctAbstract: JObj => Option[String] = record =>
stringValue(record)("abstract")
val mediaResourceDescription: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("mediaResourceDescription")
val conditionsOfUse: JObj => Option[String] = record =>
stringValue(record)("conditionsOfUse")
val regulatedByHolder
: JArr => mutable.LinkedHashMap[String, JValue] => Option[String] =
graph =>
digitalObject =>
getBlankNodesContent(graph)(digitalObject)("regulatedBy")
.collectFirst {
case res if res.obj("type").str == "holder" =>
res.obj("name").str
}
val license: JArr => mutable.LinkedHashMap[String, JValue] => Option[String] =
graph =>
digitalObject =>
getBlankNodesContent(graph)(digitalObject)("regulatedBy")
.collectFirst {
case res if res.obj("type").str == "usage" =>
res.obj("name").str
}
/* val logo: JArr => mutable.LinkedHashMap[String, JValue] => Option[String] =
graph =>
recordSet =>
getBlankNodeContent(graph)(recordSet)("heldBy")
.flatMap(v => v.get("P154").flatMap(vi => Some(vi.str))) */
val manifestId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("@id").flatMap(v => Some(s"$v/manifest"))
val dobjectId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("@id").flatMap(Some(_))
val sequenceId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("@id").flatMap(v => Some(s"$v/sequence/default"))
val canvasId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("@id").flatMap(v => Some(s"$v/canvas/default"))
val imageResourceId: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("locator")
val mimeType: JObj => Option[String] = digitalObject =>
stringValue(digitalObject)("hasMimeType")
val imageHeight: JObj => Option[Double] = digitalObject =>
numValue(digitalObject)("height")
val imageWidth: JObj => Option[Double] = digitalObject =>
numValue(digitalObject)("width")
val creationDate
: JArr => mutable.LinkedHashMap[String, JValue] => Option[String] =
graph =>
record =>
getBlankNodeContent(graph)(record)("created").flatMap(v =>
stringValue(v)("normalizedDateValue")
)
val recordId: JObj => Option[String] = record => stringValue(record)("@id").flatMap(Some(_))
}
......@@ -46,6 +46,16 @@ class ProvidedCHO (val id: String) {
def addCreationDate(createDate:Option[String]): Unit =
createDate.map(t => model.add(iri(id),DC.DATE,factory.createLiteral(t)))
def addCreator(contributor:Option[String]): Unit =
contributor.map(t => model.add(iri(id),DC.CREATOR,factory.createLiteral(t)))
def addContributor(contributor:Option[String]): Unit =
contributor.map(t => model.add(iri(id),DC.CONTRIBUTOR,factory.createLiteral(t)))
def getModel: Model = model
}
......
{
"@graph": [
{
"@id": "_:b0",
"@type": "https://www.ica.org/standards/RiC/ontology#Agent",
"name": "PASQUINI"
},
{
"@id": "_:b1",
"@type": "http://www.w3.org/2004/02/skos/core#Concept",
"prefLabel": "Parlato"
},
{
"@id": "_:b10",
"@type": "https://www.ica.org/standards/RiC/ontology#Language",
"sameAs": "http://www.wikidata.org/entity/Q150",
"name": [
{
"@language": "de",
"@value": "Französisch"
},
{
"@language": "fr",
"@value": "français"
},
{
"@language": "it",
"@value": "francese"
}
],
"resultsFrom": "_:b11",
"type": "content"
},
{
"@id": "_:b11",
"@type": "https://www.ica.org/standards/RiC/ontology#Activity",
"affects": "_:b53",
"beginningDate": "2021-29-16T16:29:55+0000",
"endDate": "2021-29-16T16:29:55+0000",
"performedBy": "_:b72",
"resultsIn": "_:b10",
"type": "enrichment"
},
{
"@id": "_:b12",
"@type": "https://www.ica.org/standards/RiC/ontology#CreationRelation",
"creationRelationHasSource": "https://memobase.ch/record/rts-002-FNB023_2591_023",
"creationRelationHasTarget": "_:b13",
"name": "Chroniqueur / Journaliste",
"type": "contributor"
},
{
"@id": "_:b13",
"@type": "https://www.ica.org/standards/RiC/ontology#Agent",
"agentIsTargetOfCreationRelation": "_:b12",
"name": "inconnu"
},
{
"@id": "_:b14",
"@type": "https://www.ica.org/standards/RiC/ontology#Identifier",
"identifier": "rts-002-FNB023_2591_023",
"type": "main"
},
{
"@id": "_:b15",
"@type": "https://www.ica.org/standards/RiC/ontology#CorporateBody",
"name": "Studio Radio Lausanne"
},
{
"@id": "_:b16",
"@type": "https://www.ica.org/standards/RiC/ontology#Agent",
"name": "ROBINSON"
},
{
"@id": "_:b17",
"@type": "https://www.ica.org/standards/RiC/ontology#Mechanism",
"name": "GenreNormalizer",
"performs": "_:b4"
},
{
"@id": "_:b18",
"@type": "http://www.w3.org/2004/02/skos/core#Concept",
"prefLabel": "Gesprochen"
},
{
"@id": "_:b19",
"@type": "https://www.ica.org/standards/RiC/ontology#CarrierType",
"name": "78 T Direktschnittplatte"
},
{
"@id": "_:b2",
"@type": "https://www.ica.org/standards/RiC/ontology#Place",
"name": "Nantes"
},
{
"@id": "_:b20",
"@type": "https://www.ica.org/standards/RiC/ontology#Identifier",
"identifier": "1905H",
"type": "callNumber"
},
{
"@id": "_:b21",
"@type": "https://www.ica.org/standards/RiC/ontology#CarrierType",
"sameAs": "http://www.wikidata.org/entity/Q17010713",
"name": [
{
"@language": "de",
"@value": "Direktschnitt"
},
{
"@language": "fr",
"@value": "L'ÉTIQUETTE MANQUANTE"
},
{
"@language": "it",
"@value": "GALATEO MANCANTE"
}
],
"resultsFrom": "_:b47"
},
{
"@id": "_:b22",
"@type": "https://www.ica.org/standards/RiC/ontology#Rule",
"name": "onsite",
"regulates": "https://memobase.ch/physical/rts-002-FNB023_2591_023-1",
"type": "access"
},
{
"@id": "_:b23",
"@type": "https://www.ica.org/standards/RiC/ontology#Rule",
"sameAs": "http://rightsstatements.org/vocab/CNE/1.0/",
"name": "Copyright Not Evaluated (CNE)",
"regulates": "https://memobase.ch/physical/rts-002-FNB023_2591_023-1",
"type": "usage"
},
{
"@id": "_:b24",
"@type": "https://www.ica.org/standards/RiC/ontology#Identifier",
"identifier": "rts-002-FNB023_2591_023-1",
"type": "main"
},
{
"@id": "_:b25",
"@type": "https://www.ica.org/standards/RiC/ontology#Agent",
"name": "ROSSELLO"
},
{
"@id": "_:b26",
"@type": "https://www.ica.org/standards/RiC/ontology#Agent",
"name": "BLUM"
},
{
"@id": "_:b27",
"@type": "https://www.ica.org/standards/RiC/ontology#CreationRelation",
"creationRelationHasSource": "https://memobase.ch/record/rts-002-FNB023_2591_023",
"creationRelationHasTarget": "_:b28",
"name": "Author",
"type": "creator"
},
{
"@id": "_:b28",
"@type": "https://www.ica.org/standards/RiC/ontology#CorporateBody",
"eventType": "CREATE",
"agentIsTargetOfCreationRelation": "_:b27",
"name": "Studio Radio Lausanne"
},
{
"@id": "_:b29",
"@type": "https://www.ica.org/standards/RiC/ontology#Activity",
"affects": "_:b31",
"beginningDate": "2021-29-16T16:29:55+0000",
"endDate": "2021-29-16T16:29:55+0000",
"performedBy": "_:b30",
"resultsIn": "_:b32",
"type": "enrichment"
},
{
"@id": "_:b3",
"@type": "http://www.w3.org/2004/02/skos/core#Concept",
"prefLabel": [
{
"@language": "de",
"@value": "Gesprochener Beitrag"
},
{
"@language": "fr",
"@value": "Contribution orale"
},
{
"@language": "it",
"@value": "Contributo parlato"
}
],
"resultsFrom": "_:b4"
},
{
"@id": "_:b30",
"@type": "https://www.ica.org/standards/RiC/ontology#Mechanism",
"name": "GenreNormalizer",
"performs": "_:b29"
},
{
"@id": "_:b31",
"@type": "http://www.w3.org/2004/02/skos/core#Concept",
"prefLabel": "Reportage"
},
{
"@id": "_:b32",
"@type": "http://www.w3.org/2004/02/skos/core#Concept",
"prefLabel": [
{
"@language": "de",
"@value": "Reportage"
},
{
"@language": "fr",
"@value": "Rapport"
},
{
"@language": "it",
"@value": "Segnala"
}
],
"resultsFrom": "_:b29"
},
{
"@id": "_:b33",
"@type": "https://www.ica.org/standards/RiC/ontology#Identifier",
"identifier": "rts-002-FNB023_2591_023-1",
"type": "main"
},
{
"@id": "_:b34",
"@type": "https://www.ica.org/standards/RiC/ontology#Agent",
"name": "MAITRE FLORIOT"
},
{
"@id": "_:b35",
"@type": "https://www.ica.org/standards/RiC/ontology#Agent",
"name": "MARTIN, Hans"
},
{
"@id": "_:b36",
"@type": "https://www.ica.org/standards/RiC/ontology#Title",
"title": "Chronique au sujet d'Otto Abetz, ex ambassadeur du Reich; DAT1/02: Arrivée du Tour cycliste de France à la Pontaise",
"type": "main"
},
{
"@id": "_:b37",
"@type": "https://www.ica.org/standards/RiC/ontology#SingleDate",
"normalizedDateValue": "1949-07-22"
},
{
"@id": "_:b38",
"@type": "http://www.w3.org/2004/02/skos/core#Concept",
"prefLabel": "Collaboration"
},
{
"@id": "_:b39",
"@type": "https://www.ica.org/standards/RiC/ontology#Agent",
"name": "MANDEL, Georges"
},
{
"@id": "_:b4",
"@type": "https://www.ica.org/standards/RiC/ontology#Activity",
"affects": "_:b18",
"beginningDate": "2021-29-16T16:29:55+0000",
"endDate": "2021-29-16T16:29:55+0000",
"performedBy": "_:b17",
"resultsIn": "_:b3",
"type": "enrichment"
},
{
"@id": "_:b40",
"@type": "https://www.ica.org/standards/RiC/ontology#Mechanism",
"name": "GenreNormalizer",
"performs": "_:b41"
},
{
"@id": "_:b41",
"@type": "https://www.ica.org/standards/RiC/ontology#Activity",
"affects": "_:b69",
"beginningDate": "2021-29-16T16:29:55+0000",
"endDate": "2021-29-16T16:29:55+0000",
"performedBy": "_:b40",
"resultsIn": "_:b60",
"type": "enrichment"