comparison pkg/controllers/stretches.go @ 3439:d7ddb21f7017 fairway-avail-csv

Prepared to write the fairway availibilty as CSV, too. WIP.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 24 May 2019 11:20:15 +0200
parents 6994602d2935
children ae6c09fbc590
comparison
equal deleted inserted replaced
3438:df6c2973f791 3439:d7ddb21f7017
19 "encoding/csv" 19 "encoding/csv"
20 "fmt" 20 "fmt"
21 "log" 21 "log"
22 "net/http" 22 "net/http"
23 "runtime" 23 "runtime"
24 "strconv"
25 "strings" 24 "strings"
26 "sync" 25 "sync"
27 "time" 26 "time"
28 27
29 "gemma.intevation.de/gemma/pkg/common"
30 "gemma.intevation.de/gemma/pkg/middleware" 28 "gemma.intevation.de/gemma/pkg/middleware"
31 "github.com/gorilla/mux" 29 "github.com/gorilla/mux"
32 ) 30 )
33 31
34 const ( 32 const (
161 vars := mux.Vars(req) 159 vars := mux.Vars(req)
162 stretch := vars["kind"] == "stretch" 160 stretch := vars["kind"] == "stretch"
163 name := vars["name"] 161 name := vars["name"]
164 162
165 mode := intervalMode(req.FormValue("mode")) 163 mode := intervalMode(req.FormValue("mode"))
166 var from, to time.Time
167 var los int
168 164
169 depthbreaks, widthbreaks := afdRefs, afdRefs 165 depthbreaks, widthbreaks := afdRefs, afdRefs
170 166
171 if f := req.FormValue("from"); f != "" { 167 from, ok := parseFormTime(rw, req, "from", time.Now().AddDate(-1, 0, 0))
172 var err error 168 if !ok {
173 if from, err = time.Parse(common.TimeFormat, f); err != nil { 169 return
174 http.Error( 170 }
175 rw, fmt.Sprintf("Invalid format for 'from': %v.", err), 171
176 http.StatusBadRequest) 172 to, ok := parseFormTime(rw, req, "to", from.AddDate(1, 0, 0))
177 return 173 if !ok {
178 } 174 return
179 } else { 175 }
180 from = time.Now().AddDate(-1, 0, 0)
181 }
182 from = from.UTC()
183
184 if t := req.FormValue("to"); t != "" {
185 var err error
186 if to, err = time.Parse(common.TimeFormat, t); err != nil {
187 http.Error(
188 rw, fmt.Sprintf("Invalid format for 'to': %v.", err),
189 http.StatusBadRequest)
190 return
191 }
192 } else {
193 to = from.AddDate(1, 0, 0)
194 }
195 to = to.UTC()
196 176
197 if to.Before(from) { 177 if to.Before(from) {
198 to, from = from, to 178 to, from = from, to
199 } 179 }
200 180
201 if l := req.FormValue("los"); l != "" { 181 los, ok := parseFormInt(rw, req, "los", 1)
202 var err error 182 if !ok {
203 if los, err = strconv.Atoi(l); err != nil { 183 return
204 http.Error(
205 rw, fmt.Sprintf("Invalid format for 'los': %v.", err),
206 http.StatusBadRequest)
207 return
208 }
209 } else {
210 los = 1
211 } 184 }
212 185
213 conn := middleware.GetDBConn(req) 186 conn := middleware.GetDBConn(req)
214 ctx := req.Context() 187 ctx := req.Context()
215 188
218 http.Error( 191 http.Error(
219 rw, fmt.Sprintf("DB error: %v.", err), 192 rw, fmt.Sprintf("DB error: %v.", err),
220 http.StatusInternalServerError) 193 http.StatusInternalServerError)
221 return 194 return
222 } 195 }
196
223 if len(bns) == 0 { 197 if len(bns) == 0 {
224 http.Error(rw, "No bottlenecks found.", http.StatusNotFound) 198 http.Error(rw, "No bottlenecks found.", http.StatusNotFound)
225 return 199 return
226 } 200 }
227 201
439 b.WriteString(err.Error()) 413 b.WriteString(err.Error())
440 } 414 }
441 return b.String() 415 return b.String()
442 } 416 }
443 417
444 func stretchAvailabilty( 418 func stretchAvailabilty(rw http.ResponseWriter, req *http.Request) {
445 _ interface{},
446 req *http.Request,
447 conn *sql.Conn,
448 ) (jr JSONResult, err error) {
449 419
450 vars := mux.Vars(req) 420 vars := mux.Vars(req)
451 stretch := vars["kind"] == "stretch" 421 stretch := vars["kind"] == "stretch"
452 name := vars["name"] 422 name := vars["name"]
453 423
454 var from, to time.Time 424 if name == "" {
455 var los int 425 http.Error(
456 426 rw,
457 depthbreaks, widthbreaks := afdRefs, afdRefs 427 fmt.Sprintf("Missing %s name", vars["kind"]),
458 428 http.StatusBadRequest,
459 if f := req.FormValue("from"); f != "" { 429 )
460 if from, err = parseTime(f, "from"); err != nil { 430 return
461 return 431 }
462 } 432
463 } else { 433 from, ok := parseFormTime(rw, req, "form", time.Now().AddDate(-1, 0, 0))
464 from = time.Now().AddDate(-1, 0, 0).UTC() 434 if !ok {
465 } 435 return
466 436 }
467 if t := req.FormValue("to"); t != "" { 437
468 if to, err = parseTime(t, "to"); err != nil { 438 to, ok := parseFormTime(rw, req, "to", from.AddDate(1, 0, 0))
469 return 439 if !ok {
470 } 440 return
471 } else {
472 to = from.AddDate(1, 0, 0).UTC()
473 } 441 }
474 442
475 if to.Before(from) { 443 if to.Before(from) {
476 to, from = from, to 444 to, from = from, to
477 } 445 }
478 446
479 if l := req.FormValue("los"); l != "" { 447 los, ok := parseFormInt(rw, req, "los", 1)
480 if los, err = parseInt(l, "los"); err != nil { 448 if !ok {
481 return 449 return
482 } 450 }
483 } else { 451
484 los = 1 452 depthbreaks, widthbreaks := afdRefs, afdRefs
485 }
486 453
487 if b := req.FormValue("depthbreaks"); b != "" { 454 if b := req.FormValue("depthbreaks"); b != "" {
488 depthbreaks = breaksToReferenceValue(b) 455 depthbreaks = breaksToReferenceValue(b)
489 } 456 }
490 457
491 if b := req.FormValue("widthbreaks"); b != "" { 458 if b := req.FormValue("widthbreaks"); b != "" {
492 widthbreaks = breaksToReferenceValue(b) 459 widthbreaks = breaksToReferenceValue(b)
493 } 460 }
494 461
462 conn := middleware.GetDBConn(req)
495 ctx := req.Context() 463 ctx := req.Context()
496 464
497 var bns stretchBottlenecks 465 bns, err := loadStretchBottlenecks(ctx, conn, stretch, name)
498 if bns, err = loadStretchBottlenecks(ctx, conn, stretch, name); err != nil { 466 if err != nil {
467 http.Error(
468 rw, fmt.Sprintf("DB error: %v.", err),
469 http.StatusInternalServerError)
499 return 470 return
500 } 471 }
501 472
502 if len(bns) == 0 { 473 if len(bns) == 0 {
503 err = JSONError{ 474 http.Error(
504 Code: http.StatusNotFound, 475 rw,
505 Message: "No bottlenecks found.", 476 "No bottlenecks found.",
506 } 477 http.StatusNotFound,
478 )
507 return 479 return
508 } 480 }
509 481
510 useDepth, useWidth := bns.contains("depth"), bns.contains("width") 482 useDepth, useWidth := bns.contains("depth"), bns.contains("width")
511 483
512 if useDepth && useWidth && len(widthbreaks) != len(depthbreaks) { 484 if useDepth && useWidth && len(widthbreaks) != len(depthbreaks) {
513 err = JSONError{ 485 http.Error(
514 Code: http.StatusBadRequest, 486 rw,
515 Message: fmt.Sprintf("class breaks lengths differ: %d != %d", 487 fmt.Sprintf("class breaks lengths differ: %d != %d",
516 len(widthbreaks), len(depthbreaks)), 488 len(widthbreaks), len(depthbreaks)),
517 } 489 http.StatusBadRequest,
490 )
518 return 491 return
519 } 492 }
520 493
521 log.Printf("info: time interval: (%v - %v)\n", from, to) 494 log.Printf("info: time interval: (%v - %v)\n", from, to)
522 495
539 } 512 }
540 loaded = append(loaded, l) 513 loaded = append(loaded, l)
541 } 514 }
542 515
543 if len(loaded) == 0 { 516 if len(loaded) == 0 {
544 err = JSONError{ 517 http.Error(
545 Code: http.StatusInternalServerError, 518 rw,
546 Message: fmt.Sprintf("No bottleneck loaded: %v", joinErrors(errors)), 519 fmt.Sprintf("No bottleneck loaded: %v", joinErrors(errors)),
547 } 520 http.StatusInternalServerError,
521 )
548 return 522 return
549 } 523 }
550 524
551 type calculation struct { 525 type calculation struct {
552 ldc, afd []time.Duration 526 ldc, afd []time.Duration
618 duration := to.Sub(from) * time.Duration(len(loaded)) 592 duration := to.Sub(from) * time.Duration(len(loaded))
619 593
620 lnwlPercents := durationsToPercentage(duration, ldc) 594 lnwlPercents := durationsToPercentage(duration, ldc)
621 afdPercents := durationsToPercentage(duration, afd) 595 afdPercents := durationsToPercentage(duration, afd)
622 596
597 _ = lnwlPercents
598 _ = afdPercents
599
600 /* // TODO: Rewrite this
601
623 type ldcOutput struct { 602 type ldcOutput struct {
624 Value float64 `json:"value"` 603 Value float64 `json:"value"`
625 Below float64 `json:"below"` 604 Below float64 `json:"below"`
626 Above float64 `json:"above"` 605 Above float64 `json:"above"`
627 } 606 }
664 }) 643 })
665 } 644 }
666 645
667 jr = JSONResult{Result: &out} 646 jr = JSONResult{Result: &out}
668 return 647 return
648 */
669 } 649 }