Commit 5e8b6246 authored by Andreas Wagner's avatar Andreas Wagner
Browse files

Move processing from routing to zenodo package.

parent fe5641fc
......@@ -2,7 +2,6 @@ package routing
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
......@@ -34,9 +33,9 @@ func SetupRoutes(conf tei2zenodo.Config) *gin.Engine {
if conf.FileAPI != "" {
APIv1.POST(conf.FileAPI, func(c *gin.Context) {
var myDeposit tei2zenodo.Deposit
var r io.ReadSeeker
var doPublish bool
var myDeposit tei2zenodo.Deposit
// Read file from Request body
buf := new(bytes.Buffer)
......@@ -50,6 +49,7 @@ func SetupRoutes(conf tei2zenodo.Config) *gin.Engine {
filename = t2zxml.GetFilename(r)
r.Seek(0, 0)
}
myDeposit.Filename = filename
// Get doPublish from request (false if not set)
if c.Request.FormValue(`doPublish`) == "True" {
......@@ -58,86 +58,12 @@ func SetupRoutes(conf tei2zenodo.Config) *gin.Engine {
doPublish = false
}
// Parse TEI file
log.Printf("=== Parse TEI file ===")
// log.Printf("Beginning of submitted file %s: %s ...", filename, file[:100])
mc := conf.Metadata
var md tei2zenodo.ZMetadata
doi, err := t2zxml.ParseTEI(r, &md, &mc)
// Send file to processing...
err := zenodo.ProcessFile(&conf, &myDeposit, r, doPublish)
if err != nil {
log.Printf("Error (%s) parsing TEI file: %80s", err, file)
AbortMsg(500, err, c)
return
}
r.Seek(0, 0)
md.DOI = ""
if doi == "" {
log.Printf("=== Create new DOI at zenodo ===")
doi, err = zenodo.CreateNewDOI(&md, &conf.ZenodoRepo)
if err != nil || doi == "" {
log.Printf("Error creating DOI reservation deposit: %v", err)
AbortMsg(500, fmt.Errorf("problem reported by zenodo: %s", err), c)
return
}
myDeposit.DepositDOI = doi
myDeposit.Metadata.DOI = doi
md.DOI = doi
} else {
log.Printf("=== Retrieve deposit for %s and create a new version ===", doi)
myDeposit.OldDOI = doi
md.RelatedIdentifiers = append(md.RelatedIdentifiers, tei2zenodo.ZIdentifier{Relation: "isNewVersionOf", Identifier: doi})
newDOI, err := zenodo.UpdateDeposit(&myDeposit, &md, &conf.ZenodoRepo)
if err != nil {
log.Printf("Error retrieving zenodo deposit for doi %s: %v", doi, err)
AbortMsg(500, fmt.Errorf("problem reported by zenodo: %s", err), c)
return
}
myDeposit.DepositDOI = newDOI
md.DOI = newDOI
}
log.Printf("=== Add new DOI to document ===")
newfile, err := t2zxml.MixinDOI(r, md.DOI)
if err != nil {
log.Printf("Error mixing new DOI into document: %v", err)
AbortMsg(500, fmt.Errorf("problem mixing new DOI into document: %s", err), c)
return
}
// log.Printf("Here is the new file:\n%s", newfile[:10000])
myDeposit.FileContent = newfile
r = strings.NewReader(newfile)
r.Seek(0, 0)
log.Printf("=== Upload to zenodo ===")
url, err := zenodo.PostFile(r, filename, &md, &conf.ZenodoRepo)
if err != nil {
log.Printf("Error sending POST request to zenodo: %v", err)
AbortMsg(500, err, c)
return
}
myDeposit.FileURI = url
log.Printf("=== Add metadata to zenodo ===")
err = zenodo.PutMetadata(&myDeposit, &md, &conf.ZenodoRepo)
if err != nil {
log.Printf("Error putting metadata: %v", err)
AbortMsg(500, err, c)
return
}
if doPublish {
log.Printf("=== Publish at zenodo ===")
err = zenodo.Publish(&md, &conf.ZenodoRepo)
if err != nil {
log.Printf("Error publishing deposit: %v", err)
AbortMsg(500, err, c)
return
}
} else {
log.Printf("=== Not published. If you want to publish, set doPublish=True as request parameter. ===")
}
log.Printf("=== All done ===")
c.JSON(200, myDeposit)
......
......@@ -13,6 +13,7 @@ import (
"strings"
"gitlab.gwdg.de/rg-mpg-de/tei2zenodo"
"gitlab.gwdg.de/rg-mpg-de/tei2zenodo/internal/pkg/t2zxml"
)
// DOIResponse stores a response from doi.org
......@@ -74,9 +75,91 @@ III. Upload metadata
params={'access_token': ACCESS_TOKEN} )
*/
// CreateDeposit creates an empty zenodo deposit and reserves a DOI
// ProcessFile takes a file and processes parsing and zenodo upload
func ProcessFile(conf *tei2zenodo.Config, myDeposit *tei2zenodo.Deposit, r io.ReadSeeker, doPublish bool) error {
mc := conf.Metadata
var md tei2zenodo.ZMetadata
// Parse TEI file
log.Printf("=== Parse TEI file ===")
// log.Printf("Beginning of submitted file %s: %s ...", filename, file[:100])
doi, err := t2zxml.ParseTEI(r, &md, &mc)
if err != nil {
log.Printf("Error parsing TEI file: %v", err)
return fmt.Errorf("error parsing TEI file: %s", err)
}
r.Seek(0, 0)
md.DOI = ""
if doi == "" {
log.Printf("=== Create new DOI at zenodo ===")
doi, err = createNewDOI(&md, &conf.ZenodoRepo)
if err != nil || doi == "" {
log.Printf("Error creating DOI reservation deposit: %v", err)
return fmt.Errorf("error creating DOI reservation deposit: %s", err)
}
myDeposit.DepositDOI = doi
myDeposit.Metadata.DOI = doi
md.DOI = doi
} else {
log.Printf("=== Retrieve deposit for %s and create a new version ===", doi)
myDeposit.OldDOI = doi
md.RelatedIdentifiers = append(md.RelatedIdentifiers, tei2zenodo.ZIdentifier{Relation: "isNewVersionOf", Identifier: doi})
newDOI, err := updateDeposit(myDeposit, &md, &conf.ZenodoRepo)
if err != nil {
log.Printf("Error retrieving zenodo deposit for doi %s: %v", doi, err)
return fmt.Errorf("error retrieving zenodo deposit for %s: %s", doi, err)
}
myDeposit.DepositDOI = newDOI
md.DOI = newDOI
}
log.Printf("=== Add new DOI to document ===")
newfile, err := t2zxml.MixinDOI(r, md.DOI)
if err != nil {
log.Printf("Error mixing new DOI into document: %v", err)
return fmt.Errorf("error mixing new DOI into document: %s", err)
}
// log.Printf("Here is the new file:\n%s", newfile[:10000])
myDeposit.FileContent = newfile
r = strings.NewReader(newfile)
r.Seek(0, 0)
log.Printf("=== Upload to zenodo ===")
url, err := postFile(r, myDeposit.Filename, &md, &conf.ZenodoRepo)
if err != nil {
log.Printf("Error uploading to zenodo, sending POST request: %v", err)
return fmt.Errorf("error uploading to zenodo, sending POST request: %s", err)
}
myDeposit.FileURI = url
log.Printf("=== Add metadata to zenodo ===")
err = putMetadata(myDeposit, &md, &conf.ZenodoRepo)
if err != nil {
log.Printf("Error putting metadata: %v", err)
return fmt.Errorf("error putting metadata to zenodo: %s", err)
}
if doPublish {
log.Printf("=== Publish at zenodo ===")
err = publish(&md, &conf.ZenodoRepo)
if err != nil {
log.Printf("Error publishing deposit: %v", err)
return fmt.Errorf("error publishing deposit: %s", err)
}
} else {
log.Printf("=== Not published. If you want to publish, set doPublish=True as request parameter. ===")
}
return nil
}
// createDeposit creates an empty zenodo deposit and reserves a DOI
// it returns the DOI of the new deposit and an error value
func CreateDeposit(targetURI string, md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) (string, error) {
func createDeposit(targetURI string, md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) (string, error) {
// Compile POST request
log.Printf(" Post request to: %s", targetURI)
......@@ -143,11 +226,11 @@ func CreateDeposit(targetURI string, md *tei2zenodo.ZMetadata, conf *tei2zenodo.
return doi, nil
}
// CreateNewDOI creates a Deposit from Scratch
// createNewDOI creates a Deposit from Scratch
// it returns a new zenodo DOI for the deposit and an error value
func CreateNewDOI(md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) (string, error) {
func createNewDOI(md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) (string, error) {
targetURI := conf.Host + ":" + strconv.Itoa(int(conf.Port)) + "/api/deposit/depositions"
doi, err := CreateDeposit(targetURI, md, conf)
doi, err := createDeposit(targetURI, md, conf)
if err != nil {
log.Printf("Problem creating new DOI/deposit: %v ...", err)
return "", fmt.Errorf("problem creating new DOI/deposit: %s", err)
......@@ -155,9 +238,9 @@ func CreateNewDOI(md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) (string
return doi, nil
}
// UpdateDeposit retrieves a zenodo deposit based on a gived DOI and creates a new version
// updateDeposit retrieves a zenodo deposit based on a gived DOI and creates a new version
// it returns a new zenodo DOI for the deposit and an error value
func UpdateDeposit(d *tei2zenodo.Deposit, md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) (string, error) {
func updateDeposit(d *tei2zenodo.Deposit, md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) (string, error) {
if d.OldDOI[:len(conf.Prefix)] != conf.Prefix {
log.Printf("Problem: DOI %s is not a zenodo DOI.", d.OldDOI)
return "", fmt.Errorf("invalid DOI value")
......@@ -201,7 +284,7 @@ func UpdateDeposit(d *tei2zenodo.Deposit, md *tei2zenodo.ZMetadata, conf *tei2ze
newVersionLink := d.Links.NewVersionURI
log.Printf(" Now get new version at %s", newVersionLink)
newDOI, err := CreateDeposit(newVersionLink, md, conf)
newDOI, err := createDeposit(newVersionLink, md, conf)
if err != nil {
log.Printf("Problem creating new version/deposit: %v ...", err)
return "", fmt.Errorf("problem creating new version/deposit: %s", err)
......@@ -211,9 +294,9 @@ func UpdateDeposit(d *tei2zenodo.Deposit, md *tei2zenodo.ZMetadata, conf *tei2ze
return newDOI, nil
}
// GetFiles gets all files associated to a deposit
// getFiles gets all files associated to a deposit
// it returns a slice of tei2zenodo.ZFile objects
func GetFiles(doi string, conf *tei2zenodo.RepoConfig) ([]tei2zenodo.ZFile, error) {
func getFiles(doi string, conf *tei2zenodo.RepoConfig) ([]tei2zenodo.ZFile, error) {
if doi[:len(conf.Prefix)] != conf.Prefix {
log.Printf("Problem: DOI %s is not a zenodo DOI.", doi)
return nil, fmt.Errorf("invalid DOI value")
......@@ -257,9 +340,9 @@ func GetFiles(doi string, conf *tei2zenodo.RepoConfig) ([]tei2zenodo.ZFile, erro
return files, nil
}
// DeleteFileByID deletes a file from a zenodo deposit by its ID
// deleteFileByID deletes a file from a zenodo deposit by its ID
// it returns an error value
func DeleteFileByID(doi string, id string, conf *tei2zenodo.RepoConfig) error {
func deleteFileByID(doi string, id string, conf *tei2zenodo.RepoConfig) error {
if doi[:len(conf.Prefix)] != conf.Prefix {
log.Printf("Problem: DOI %s is not a zenodo DOI.", doi)
return fmt.Errorf("invalid DOI value")
......@@ -294,15 +377,15 @@ func DeleteFileByID(doi string, id string, conf *tei2zenodo.RepoConfig) error {
return nil
}
// DeleteFileByName deletes a file from a zenodo deposit by its name
// it returns an error value
func DeleteFileByName(doi string, filename string, conf *tei2zenodo.RepoConfig) error {
// mustDeleteFileByName deletes a file from a zenodo deposit by its name
// it returns an error value and fails when the file is not present
func mustDeleteFileByName(doi string, filename string, conf *tei2zenodo.RepoConfig) error {
if doi[:len(conf.Prefix)] != conf.Prefix {
log.Printf("Problem: DOI %s is not a zenodo DOI.", doi)
return fmt.Errorf("invalid DOI value")
}
files, err := GetFiles(doi, conf)
files, err := getFiles(doi, conf)
if err != nil {
log.Printf("Problem: Could not get files for DOI %s.", doi)
return fmt.Errorf("could not get files for %s", doi)
......@@ -310,7 +393,7 @@ func DeleteFileByName(doi string, filename string, conf *tei2zenodo.RepoConfig)
for _, f := range files {
log.Printf("test %s...", f.Filename)
if f.Filename == filename {
err = DeleteFileByID(doi, f.ID, conf)
err = deleteFileByID(doi, f.ID, conf)
if err != nil {
log.Printf("Problem: Could not delete file %s.", f.ID)
return fmt.Errorf("could not delete file %s", f.ID)
......@@ -322,23 +405,23 @@ func DeleteFileByName(doi string, filename string, conf *tei2zenodo.RepoConfig)
return fmt.Errorf("no file with name %s found in deposit %s", filename, doi)
}
// DeleteIfExistsFileByName deletes a file from a zenodo deposit by its name.
// deleteFileByName deletes a file from a zenodo deposit by its name.
// it does not raise an error if the file does not exist in the first place.
// it returns an error value
func DeleteIfExistsFileByName(doi string, filename string, conf *tei2zenodo.RepoConfig) error {
func deleteFileByName(doi string, filename string, conf *tei2zenodo.RepoConfig) error {
if doi[:len(conf.Prefix)] != conf.Prefix {
log.Printf("Problem: DOI %s is not a zenodo DOI.", doi)
return fmt.Errorf("invalid DOI value")
}
files, err := GetFiles(doi, conf)
files, err := getFiles(doi, conf)
if err != nil {
log.Printf("Problem: Could not get files for DOI %s.", doi)
return fmt.Errorf("could not get files for %s", doi)
}
for _, f := range files {
if f.Filename == filename {
err = DeleteFileByID(doi, f.ID, conf)
err = deleteFileByID(doi, f.ID, conf)
if err != nil {
log.Printf("Problem: Could not delete file %s.", f.ID)
return fmt.Errorf("could not delete file %s", f.ID)
......@@ -351,9 +434,9 @@ func DeleteIfExistsFileByName(doi string, filename string, conf *tei2zenodo.Repo
return nil
}
// PostFile posts a file to zenodo, taking the id from the md.DOI field
// postFile posts a file to zenodo, taking the id from the md.DOI field
// it returns an URI for the upload and an error value
func PostFile(r io.Reader, filename string, md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) (string, error) {
func postFile(r io.Reader, filename string, md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) (string, error) {
if md.DOI[:len(conf.Prefix)] != conf.Prefix {
log.Printf("Problem: DOI %s is not a zenodo DOI.", md.DOI)
return "", fmt.Errorf("invalid DOI value")
......@@ -361,7 +444,7 @@ func PostFile(r io.Reader, filename string, md *tei2zenodo.ZMetadata, conf *tei2
id := md.DOI[len(conf.Prefix):]
log.Printf("Make sure no file named %s exists in doi %s.", filename, md.DOI)
err := DeleteIfExistsFileByName(md.DOI, filename, conf)
err := deleteFileByName(md.DOI, filename, conf)
if err != nil {
log.Printf("Problem deleting file %s: %v", filename, err)
return "", fmt.Errorf("problem deleting file %s: %s", filename, err)
......@@ -442,8 +525,8 @@ func PostFile(r io.Reader, filename string, md *tei2zenodo.ZMetadata, conf *tei2
return parsedContent.Links.DownloadURI, nil
}
// PutMetadata adds metadata to an existing deposit and returns an error value
func PutMetadata(d *tei2zenodo.Deposit, md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) error {
// putMetadata adds metadata to an existing deposit and returns an error value
func putMetadata(d *tei2zenodo.Deposit, md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) error {
if md.DOI[:len(conf.Prefix)] != conf.Prefix {
log.Printf("Problem: DOI %s is not a zenodo DOI.", md.DOI)
return fmt.Errorf("invalid DOI value")
......@@ -506,8 +589,8 @@ func PutMetadata(d *tei2zenodo.Deposit, md *tei2zenodo.ZMetadata, conf *tei2zeno
return nil
}
// Publish instructs zenodo to publish the deposit described in md and returns an error value
func Publish(md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) error {
// publish instructs zenodo to publish the deposit described in md and returns an error value
func publish(md *tei2zenodo.ZMetadata, conf *tei2zenodo.RepoConfig) error {
if md.DOI[:len(conf.Prefix)] != conf.Prefix {
log.Printf("Problem: DOI %s is not a zenodo DOI.", md.DOI)
return fmt.Errorf("invalid DOI value")
......
......@@ -55,6 +55,7 @@ type Deposit struct {
DepositDOI string `json:"doi"`
DOIURL string `json:"doi_url"`
FileContent string
Filename string
Files []ZFile
Filesize int64
FileURI string
......
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