changeset 1239:d842d9d10872

Sounding result import: Added the feature to override bottleneck, EPSG, depth reference and date in meta.json by POST arguments.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 20 Nov 2018 17:04:06 +0100
parents 442399fc1b71
children 9b0a7b3ea297
files pkg/controllers/srimports.go pkg/imports/sr.go
diffstat 2 files changed, 102 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/pkg/controllers/srimports.go	Tue Nov 20 13:05:50 2018 +0100
+++ b/pkg/controllers/srimports.go	Tue Nov 20 17:04:06 2018 +0100
@@ -25,16 +25,18 @@
 	"net/http"
 	"os"
 	"path/filepath"
+	"strconv"
 	"sync"
 	"time"
 
+	"github.com/gorilla/mux"
+
 	"gemma.intevation.de/gemma/pkg/auth"
 	"gemma.intevation.de/gemma/pkg/common"
 	"gemma.intevation.de/gemma/pkg/config"
 	"gemma.intevation.de/gemma/pkg/imports"
 	"gemma.intevation.de/gemma/pkg/misc"
 	"gemma.intevation.de/gemma/pkg/models"
-	"github.com/gorilla/mux"
 )
 
 const (
@@ -101,18 +103,64 @@
 	return dir, nil
 }
 
+func fetchSoundingResultMetaOverrides(sr *imports.SoundingResult, req *http.Request) error {
+
+	if v := req.FormValue("epsg"); v != "" {
+		epsg, err := strconv.ParseUint(v, 10, 32)
+		if err != nil {
+			return err
+		}
+		srid := uint(epsg)
+		sr.EPSG = &srid
+	}
+
+	if v := req.FormValue("date"); v != "" {
+		date, err := time.Parse(models.SoundingResultDateFormat, v)
+		if err != nil {
+			return err
+		}
+		sr.Date = &models.SoundingResultDate{date}
+	}
+
+	if v := req.FormValue("depth-reference"); v != "" {
+		sr.DepthReference = &v
+	}
+
+	if v := req.FormValue("bottleneck"); v != "" {
+		sr.Bottleneck = &v
+	}
+
+	return nil
+}
+
 func importSoundingResult(rw http.ResponseWriter, req *http.Request) {
 
+	sr := new(imports.SoundingResult)
+
+	if err := fetchSoundingResultMetaOverrides(sr, req); err != nil {
+		log.Printf("error: %v\n", err)
+		http.Error(rw, "error: "+err.Error(), http.StatusBadRequest)
+		return
+	}
+
 	dir, err := fetchSoundingResult(req)
 	if err != nil {
 		log.Printf("error: %v\n", err)
 		http.Error(rw, "error: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
+	sr.Dir = dir
+
+	serialized, err := sr.ToString()
+	if err != nil {
+		log.Printf("error: %v\n", err)
+		http.Error(rw, "error: "+err.Error(), http.StatusInternalServerError)
+		return
+	}
 
 	session, _ := auth.GetSession(req)
 
-	jobID, err := imports.AddJob(imports.SRJobKind, session.User, dir)
+	jobID, err := imports.AddJob(imports.SRJobKind, session.User, serialized)
 	if err != nil {
 		log.Printf("error: %v\n", err)
 		http.Error(rw, "error: "+err.Error(), http.StatusInternalServerError)
--- a/pkg/imports/sr.go	Tue Nov 20 13:05:50 2018 +0100
+++ b/pkg/imports/sr.go	Tue Nov 20 17:04:06 2018 +0100
@@ -20,6 +20,7 @@
 	"crypto/sha1"
 	"database/sql"
 	"encoding/hex"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
@@ -38,7 +39,15 @@
 	"gemma.intevation.de/gemma/pkg/octree"
 )
 
-type SoundingResult string
+type SoundingResult struct {
+	Dir string `json:"dir"`
+
+	// Override data
+	Date           *models.SoundingResultDate `json:"date,omitempty"`
+	Bottleneck     *string                    `json:"bottleneck,omitempty"`
+	EPSG           *uint                      `json:"epsg,omitempty"`
+	DepthReference *string                    `json:"depth-reference,omitempty"`
+}
 
 const (
 	contourStepWidth = 0.1
@@ -54,7 +63,11 @@
 }
 
 func (srJobCreator) Create(_ JobKind, data string) (Job, error) {
-	return SoundingResult(data), nil
+	sr := new(SoundingResult)
+	if err := sr.FromString(data); err != nil {
+		return nil, err
+	}
+	return sr, nil
 }
 
 func (srJobCreator) Depends() []string {
@@ -138,14 +151,26 @@
 `
 )
 
-func (sr SoundingResult) Do(
+func (sr *SoundingResult) FromString(data string) error {
+	return json.NewDecoder(strings.NewReader(data)).Decode(sr)
+}
+
+func (sr *SoundingResult) ToString() (string, error) {
+	var b strings.Builder
+	if err := json.NewEncoder(&b).Encode(sr); err != nil {
+		return "", err
+	}
+	return b.String(), nil
+}
+
+func (sr *SoundingResult) Do(
 	importID int64,
 	ctx context.Context,
 	conn *sql.Conn,
 	feedback Feedback,
 ) error {
 
-	z, err := zip.OpenReader(filepath.Join(string(sr), "sr.zip"))
+	z, err := zip.OpenReader(filepath.Join(sr.Dir, "sr.zip"))
 	if err != nil {
 		return err
 	}
@@ -157,7 +182,7 @@
 		return errors.New("Cannot find 'meta.json'")
 	}
 
-	m, err := loadMeta(mf)
+	m, err := sr.loadMeta(mf)
 	if err != nil {
 		return err
 	}
@@ -269,18 +294,36 @@
 	return err
 }
 
-func (sr SoundingResult) CleanUp() error {
-	return os.RemoveAll(string(sr))
+func (sr *SoundingResult) CleanUp() error {
+	return os.RemoveAll(sr.Dir)
 }
 
-func loadMeta(f *zip.File) (*models.SoundingResultMeta, error) {
+func (sr *SoundingResult) loadMeta(f *zip.File) (*models.SoundingResultMeta, error) {
 	r, err := f.Open()
 	if err != nil {
 		return nil, err
 	}
 	defer r.Close()
 	var m models.SoundingResultMeta
-	return &m, m.Decode(r)
+	if err := m.Decode(r); err != nil {
+		return nil, err
+	}
+
+	// Apply overrides
+	if sr.Date != nil {
+		m.Date = *sr.Date
+	}
+	if sr.Bottleneck != nil {
+		m.Bottleneck = *sr.Bottleneck
+	}
+	if sr.EPSG != nil {
+		m.EPSG = *sr.EPSG
+	}
+	if sr.DepthReference != nil {
+		m.DepthReference = *sr.DepthReference
+	}
+
+	return &m, nil
 }
 
 func loadXYZReader(r io.Reader, feedback Feedback) (octree.MultiPointZ, error) {