Commit 75696cb9 authored by Andreas Wagner's avatar Andreas Wagner
Browse files

Parse metadata config.

parent e9f2a83e
......@@ -17,7 +17,7 @@ func main() {
conf.Configure(&Config)
log.Printf("[main/main] Config: %+v", Config)
router := routing.SetupRoutes()
router := routing.SetupRoutes(Config)
router.Run(":" + strconv.FormatInt(Config.ListenSpec, 10))
// router.RunTLS(":"+strconv.Itoa(Config.ListenSpec), "./policey_server.cert", "./policey_server.key")
}
......@@ -14,18 +14,70 @@
"repo": "svsal"
}
],
"metadata_fields": [
{
"field": "creator",
"xpath": "//author[1]"
},
{
"field": "license",
"xpath": "//license[1]"
},
{
"field": "title",
"xpath": "//title[1]"
}
]
"metadata": {
"fields": [
{
"field": "doi",
"xpath": "//publicationStmt//idno[@type='doi']"
},
{
"field": "title",
"xpath": "//titleStmt//title[@type='main']"
},
{
"field": "creators",
"subfields": [
{
"field": "name",
"xpath": "//titleStmt/author"
},
{
"field": "affiliation",
"xpath": ""
},
{
"field": "orcid",
"xpath": ""
},
{
"field": "gnd",
"xpath": ""
}
]
},
{
"field": "publication_date",
"xpath": "//publicationStmt/date"
},
{
"field": "license",
"xpath": "//publicationStmt/availability/license/@target"
},
{
"field": "contributors",
"subfields": [
{
"field": "name",
"xpath": "//titleStmt/editor"
},
{
"field": "type",
"xpath": "//titleStmt/editor/@role"
},
{
"field": "affiliation",
"xpath": ""
},
{
"field": "orcid",
"xpath": ""
},
{
"field": "gnd",
"xpath": ""
}
]
}
]
}
}
......@@ -14,7 +14,7 @@ import (
)
// SetupRoutes establishes the various API endpoints.
func SetupRoutes() *gin.Engine {
func SetupRoutes(conf tei2zenodo.Config) *gin.Engine {
// Create a gin router with logrus router and stock recovery
// logger.Infof("Starting routing...")
router := gin.New()
......@@ -36,8 +36,9 @@ func SetupRoutes() *gin.Engine {
// log.Printf("Here is the file: %s", buf)
// Parse TEI file
var md *tei2zenodo.ZMetadata
doi, err := xml.ParseTEI(md, buf)
mc := conf.Metadata
var md tei2zenodo.ZMetadata
doi, err := xml.ParseTEI(buf, &md, &mc)
if err != nil {
log.Printf("Error (%s) parsing TEI file: %v", err, buf)
AbortMsg(500, err, c)
......@@ -46,7 +47,7 @@ func SetupRoutes() *gin.Engine {
switch doi {
case "":
// prereserve doi
err := zenodo.GetDOI(buf, md)
err := zenodo.GetDOI(buf, &md)
if err != nil {
log.Printf("Error creating DOI reservation deposit: %v", err)
AbortMsg(500, err, c)
......@@ -81,6 +82,7 @@ func SetupRoutes() *gin.Engine {
*/
default:
log.Printf("DOI present: %v", doi)
log.Printf("Title: %v", md.Title)
}
})
APIv1.GET("/webhook", func(c *gin.Context) {
......
......@@ -3,13 +3,14 @@ package xml
import (
"bytes"
"log"
"reflect"
"github.com/antchfx/xmlquery"
"gitlab.gwdg.de/rg-mpg-de/tei2zenodo"
)
// ParseTEI reads a TEI file and parses its metadata into a ZMetadata variable. Returns a doi (maybe empty) and an error value.
func ParseTEI(md *tei2zenodo.ZMetadata, buf *bytes.Buffer) (string, error) {
func ParseTEI(buf *bytes.Buffer, md *tei2zenodo.ZMetadata, conf *tei2zenodo.MetadataConfig) (string, error) {
// This is wih antchfx/xmlquery...
doc, err := xmlquery.Parse(buf)
......@@ -27,70 +28,42 @@ func ParseTEI(md *tei2zenodo.ZMetadata, buf *bytes.Buffer) (string, error) {
doi = ""
log.Printf("no doi found.\n")
}
return doi, nil
/*
list := xmlquery.Find(doc, "//author")
//Iterate through the fields of a struct
v := reflect.ValueOf(md)
typeOfS := v.Type()
md.DOI = doi
//Iterate through the fields of the metadata struct and see if we have a config for them
s := reflect.ValueOf(md).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
structFieldname := typeOfT.Field(i).Name
// structFieldtype := f.Type()
// structFieldvalue := f.Interface()
jsonFieldname := typeOfT.Field(i).Tag.Get("json")
for j := range conf.Fields {
if conf.Fields[j].Field == jsonFieldname && conf.Fields[j].XPath != "" {
// log.Printf("Found config for %s: %s", jsonFieldname, conf.Fields[j].XPath)
xpath := conf.Fields[j].XPath
t := xmlquery.FindOne(doc, xpath)
var u string
if n := t; t != nil {
u = n.InnerText()
log.Printf("%s found. Set to %v ...\n", structFieldname, n.InnerText())
f.SetString(u)
}
for i := 0; i< v.NumField(); i++ {
val := v.Field(i).Interface().(int)
s.Base[typeOfS.Field(i).Name] = val
}
}
return s
}
for i, n := range xmlquery.Find(doc, "//item/title") {
fmt.Printf("#%d %s\n", i, n.InnerText())
}
// for i, n := range xmlquery.Find(doc, "//item/title") {
// log.Printf("#%d %s\n", i, n.InnerText())
// }
/*
expr, err := xpath.Compile("sum(//book/price)")
price := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64)
*/
// This is with standard xml module, decoding everything...
/*
decoder := xml.NewDecoder(strings.NewReader(string(buf)))
for {
// err is ignore here. IF you are reading from a XML file
// do not ignore err and also check for io.EOF
token, _ := decoder.Token()
if token == nil {
break
}
switch Element := token.(type) {
case xml.StartElement:
if Element.Name.Local == "teiHeader" {
fmt.Println("Element name is : ", Element.Name.Local)
err := decoder.DecodeElement(&l, &Element)
if err != nil {
fmt.Println(err)
}
fmt.Println("Element value is : ", l.Loc)
}
}
// example on handling XML attribute
return doi, nil
switch Element := token.(type) {
case xml.StartElement:
if Element.Name.Local == "title" {
fmt.Println("Element name is : ", Element.Name.Local)
attrName := Element.Attr[0].Name.Local
attrValue := Element.Attr[0].Value
fmt.Printf("Attribute name is [%s] and value is [%s] \n", attrName, attrValue)
}
}
}
*/
}
No preview for this file type
......@@ -4,13 +4,13 @@ package tei2zenodo
// Config is the struct of the application's general configuration.
type Config struct {
Domain string
ListenSpec int64
APIURI string
Repo RepoConfig
AllowedGit GitConfig
MetadataFields []MetadataConfig
Log LoggingConfig
Domain string
ListenSpec int64
APIURI string
Repo RepoConfig
AllowedGit GitConfig
Metadata MetadataConfig
Log LoggingConfig
}
// LoggingConfig specifies all the parameters needed for logging.
......@@ -35,8 +35,13 @@ type GitConfig struct {
// MetadataConfig specifies metadata fields and xpaths to retrieve their values if the need to be different from the defaults.
type MetadataConfig struct {
Field string
XPath string
Fields []metadataField
}
type metadataField struct {
Field string
XPath string
Subfields []metadataField
}
// Link HATEOAS-links our resources
......@@ -56,8 +61,6 @@ type ZMetadata struct {
// article, patent, preprint, deliverable, milestone, proposal, report,
// softwaredocumentation, taxonomictreatment, technicalnote, thesis,
// workingpaper, other
ImageType string `json:"image_type"` // mandatory if upload_type=image
// values: figure, plot, drawing, diagram, photo, other
PublicationDate string `json:"publication_date"` // mandatory, in ISO8601 format (YYYY-MM-DD)
Title string `json:"title"` // mandatory
Creators []ZCreator `json:"creators"` // mandatory
......
......@@ -67,6 +67,7 @@
</xi:include>
<date type="digitizedEd" when="2018-07-10">2018-07-10</date>
<idno>
<idno type="doi">10.1234/zenodo.567890</idno>
<idno xml:id="urlid">https://id.salamanca.school/texts/W0004</idno>
<idno xml:id="urltei">https://id.salamanca.school/texts/W0004?format=tei</idno>
<idno xml:id="urlhtml">https://id.salamanca.school/texts/W0004?format=html</idno>
......@@ -2444,4 +2445,4 @@
</div>
</back>
</text>
</TEI>
\ No newline at end of file
</TEI>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment