Mercurial > gemma
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 } |