diff pkg/controllers/fwa.go @ 5576:2b862190aee4 surveysperbottleneckid

merge with default
author Thomas Junk <thomas.junk@intevation.de>
date Tue, 08 Feb 2022 10:20:26 +0100
parents 5f47eeea988d
children
line wrap: on
line diff
--- a/pkg/controllers/fwa.go	Wed Jul 21 15:14:40 2021 +0200
+++ b/pkg/controllers/fwa.go	Tue Feb 08 10:20:26 2022 +0100
@@ -18,7 +18,6 @@
 	"database/sql"
 	"encoding/csv"
 	"fmt"
-	"log"
 	"net/http"
 	"sort"
 	"strconv"
@@ -28,6 +27,7 @@
 	"github.com/gorilla/mux"
 
 	"gemma.intevation.de/gemma/pkg/common"
+	"gemma.intevation.de/gemma/pkg/log"
 	"gemma.intevation.de/gemma/pkg/middleware"
 )
 
@@ -219,7 +219,7 @@
 	}
 
 	if err != nil {
-		log.Printf("error: %v\n", err)
+		log.Errorf("%v\n", err)
 		http.Error(rw, "cannot extract bottlenecks", http.StatusBadRequest)
 		return
 	}
@@ -233,37 +233,45 @@
 	// load validities and limiting factors
 	for i := range bns {
 		if err := bns[i].loadLimitingValidities(ctx, conn, from, to); err != nil {
-			log.Printf("error: %v\n", err)
+			log.Errorf("%v\n", err)
 			http.Error(rw, "cannot load validities", http.StatusInternalServerError)
 			return
 		}
 		// load LCDs
 		if err := bns[i].loadLDCs(ctx, conn, from, to); err != nil {
-			log.Printf("error: %v\n", err)
+			log.Errorf("%v\n", err)
 			http.Error(rw, "cannot load LDCs", http.StatusInternalServerError)
 			return
 		}
 		// load values
 		if err := bns[i].loadValues(ctx, conn, from, to, los); err != nil {
-			log.Printf("error: %v\n", err)
+			log.Errorf("%v\n", err)
 			http.Error(rw, "cannot load values", http.StatusInternalServerError)
 			return
 		}
 	}
 
 	// separate breaks for depth and width
-	var (
-		breaks       = parseBreaks(req.FormValue("breaks"), afdRefs)
-		depthBreaks  = parseBreaks(req.FormValue("depthbreaks"), breaks)
-		widthBreaks  = parseBreaks(req.FormValue("widthbreaks"), breaks)
-		chooseBreaks = [...][]float64{
-			limitingDepth: depthBreaks,
-			limitingWidth: widthBreaks,
-		}
+	breaks, ok := parseBreaks(rw, req, "breaks", afdRefs)
+	if !ok {
+		return
+	}
+	depthBreaks, ok := parseBreaks(rw, req, "depthbreaks", breaks)
+	if !ok {
+		return
+	}
+	widthBreaks, ok := parseBreaks(rw, req, "widthbreaks", breaks)
+	if !ok {
+		return
+	}
 
-		useDepth = bns.hasLimiting(limitingDepth, from, to)
-		useWidth = bns.hasLimiting(limitingWidth, from, to)
-	)
+	chooseBreaks := [...][]float64{
+		limitingDepth: depthBreaks,
+		limitingWidth: widthBreaks,
+	}
+
+	useDepth := bns.hasLimiting(limitingDepth, from, to)
+	useWidth := bns.hasLimiting(limitingWidth, from, to)
 
 	if useDepth && useWidth && len(widthBreaks) != len(depthBreaks) {
 		http.Error(
@@ -292,7 +300,7 @@
 
 	if err := out.Write(record); err != nil {
 		// Too late for HTTP status message.
-		log.Printf("error: %v\n", err)
+		log.Errorf("%v\n", err)
 		return
 	}
 
@@ -384,12 +392,12 @@
 				}
 			}
 
-			if min := minClass(bns[i].measurements.classify(
+			classes := bns[i].measurements.classify(
 				current, next,
 				chooseBreaks[vs.limiting],
-				limitingAccess[vs.limiting]),
-				12*time.Hour,
-			); min < lowest {
+				limitingAccess[vs.limiting])
+
+			if min := minClass(classes, 12*time.Hour); min < lowest {
 				lowest = min
 			}
 		}
@@ -409,7 +417,7 @@
 		if finish(next) {
 			if err := write(); err != nil {
 				// Too late for HTTP status message.
-				log.Printf("error: %v\n", err)
+				log.Errorf("%v\n", err)
 				return
 			}
 
@@ -427,14 +435,14 @@
 	if totalDays > 0 {
 		if err := write(); err != nil {
 			// Too late for HTTP status message.
-			log.Printf("error: %v\n", err)
+			log.Errorf("%v\n", err)
 			return
 		}
 	}
 
 	for i, days := range missingLDCs {
 		if missingLDCs[i] > 0 {
-			log.Printf("warn: Missing LDCs for %s on %d days.\n",
+			log.Warnf("warn: Missing LDCs for %s on %d days.\n",
 				bns[i].id, days)
 		}
 	}
@@ -442,7 +450,7 @@
 	out.Flush()
 	if err := out.Error(); err != nil {
 		// Too late for HTTP status message.
-		log.Printf("error: %v\n", err)
+		log.Errorf("%v\n", err)
 	}
 }
 
@@ -488,25 +496,42 @@
 	}
 }
 
-func breaksToReferenceValue(breaks string) []float64 {
+func breaksToReferenceValue(breaks string) ([]float64, error) {
 	parts := strings.Split(breaks, ",")
 	var values []float64
 
 	for _, part := range parts {
 		part = strings.TrimSpace(part)
-		if v, err := strconv.ParseFloat(part, 64); err == nil {
-			values = append(values, v)
+		v, err := strconv.ParseFloat(part, 64)
+		if err != nil {
+			return nil, err
 		}
+		values = append(values, v)
 	}
 
-	return common.DedupFloat64s(values)
+	return common.DedupFloat64s(values), nil
 }
 
-func parseBreaks(breaks string, defaults []float64) []float64 {
-	if breaks != "" {
-		return breaksToReferenceValue(breaks)
+func parseBreaks(
+	rw http.ResponseWriter, req *http.Request,
+	parameter string,
+	defaults []float64,
+) ([]float64, bool) {
+
+	breaks := strings.TrimSpace(req.FormValue(parameter))
+	if breaks == "" {
+		return defaults, true
 	}
-	return defaults
+
+	defaults, err := breaksToReferenceValue(breaks)
+	if err != nil {
+		msg := fmt.Sprintf("Parameter '%s' is invalid: %s.", parameter, err)
+		log.Errorf("%s\n", msg)
+		http.Error(rw, msg, http.StatusBadRequest)
+		return nil, false
+	}
+
+	return defaults, true
 }
 
 func (tr *timeRange) intersects(from, to time.Time) bool {
@@ -561,7 +586,7 @@
 	case "width":
 		return limitingWidth
 	default:
-		log.Printf("warn: unknown limitation '%s'. default to 'depth'\n", limiting)
+		log.Warnf("unknown limitation '%s'. default to 'depth'\n", limiting)
 		return limitingDepth
 	}
 }