Add convective outlook HTTP routes
This commit is contained in:
@@ -8,7 +8,9 @@ import (
|
||||
"time"
|
||||
|
||||
"gitea.maximumdirect.net/ejr/feedapi/bind"
|
||||
apierrors "gitea.maximumdirect.net/ejr/feedapi/errors"
|
||||
"gitea.maximumdirect.net/ejr/weatherapi/internal/adapters/inbound/httpapi/presenter"
|
||||
"gitea.maximumdirect.net/ejr/weatherapi/internal/app"
|
||||
)
|
||||
|
||||
type queryRequest struct {
|
||||
@@ -26,6 +28,12 @@ type timezoneQueryRequest struct {
|
||||
Timezone *time.Location
|
||||
}
|
||||
|
||||
type outlookQueryRequest struct {
|
||||
Units presenter.Units
|
||||
Timezone *time.Location
|
||||
Filter app.OutlookFilter
|
||||
}
|
||||
|
||||
func bindQuery(r *http.Request) (queryRequest, error) {
|
||||
normalizeCommonQueryValue(r, "units")
|
||||
normalizeCommonQueryValue(r, "format")
|
||||
@@ -135,3 +143,91 @@ func bindPrecisionQueryInternal(r *http.Request, allowTimezone bool) (precisionQ
|
||||
Timezone: tz,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func bindOutlookQuery(r *http.Request) (outlookQueryRequest, error) {
|
||||
return bindOutlookQueryInternal(r, true)
|
||||
}
|
||||
|
||||
func bindOutlookLocationQuery(r *http.Request) (outlookQueryRequest, error) {
|
||||
return bindOutlookQueryInternal(r, false)
|
||||
}
|
||||
|
||||
func bindOutlookQueryInternal(r *http.Request, allowContainsLocation bool) (outlookQueryRequest, error) {
|
||||
normalizeCommonQueryValue(r, "units")
|
||||
normalizeCommonQueryValue(r, "format")
|
||||
normalizeCommonQueryValue(r, "outlookType")
|
||||
|
||||
allowedExtra := []string{"tz", "TZ", "day", "outlookType"}
|
||||
if allowContainsLocation {
|
||||
allowedExtra = append(allowedExtra, "containsLocation")
|
||||
}
|
||||
|
||||
common, err := bind.CommonQueryParams(r, bind.QueryPolicy{
|
||||
AllowUnits: true,
|
||||
AllowFormat: true,
|
||||
DefaultUnits: string(presenter.UnitsMetric),
|
||||
RejectUnknown: true,
|
||||
}, allowedExtra...)
|
||||
if err != nil {
|
||||
return outlookQueryRequest{}, err
|
||||
}
|
||||
|
||||
units := presenter.Units(strings.ToLower(strings.TrimSpace(common.Units)))
|
||||
if units == "" {
|
||||
units = presenter.UnitsMetric
|
||||
}
|
||||
|
||||
tz, err := parseTimezoneQuery(r)
|
||||
if err != nil {
|
||||
return outlookQueryRequest{}, err
|
||||
}
|
||||
|
||||
filter, err := bindOutlookFilter(r, allowContainsLocation)
|
||||
if err != nil {
|
||||
return outlookQueryRequest{}, err
|
||||
}
|
||||
|
||||
return outlookQueryRequest{
|
||||
Units: units,
|
||||
Timezone: tz,
|
||||
Filter: filter,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func bindOutlookFilter(r *http.Request, allowContainsLocation bool) (app.OutlookFilter, error) {
|
||||
var filter app.OutlookFilter
|
||||
|
||||
if strings.TrimSpace(r.URL.Query().Get("day")) != "" {
|
||||
day, err := bind.OptionalInt(r, "day", 0)
|
||||
if err != nil {
|
||||
return app.OutlookFilter{}, err
|
||||
}
|
||||
if day < 1 || day > 3 {
|
||||
return app.OutlookFilter{}, apierrors.InvalidParameter("day must be one of [1, 2, 3]")
|
||||
}
|
||||
filter.Day = &day
|
||||
}
|
||||
|
||||
outlookType := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("outlookType")))
|
||||
if outlookType != "" {
|
||||
switch outlookType {
|
||||
case "categorical", "tornado", "hail", "wind":
|
||||
filter.OutlookType = outlookType
|
||||
default:
|
||||
return app.OutlookFilter{}, apierrors.InvalidParameter("outlookType must be one of [categorical, tornado, hail, wind]")
|
||||
}
|
||||
}
|
||||
|
||||
if strings.TrimSpace(r.URL.Query().Get("containsLocation")) != "" {
|
||||
if !allowContainsLocation {
|
||||
return app.OutlookFilter{}, apierrors.InvalidParameter("containsLocation is not allowed on this endpoint")
|
||||
}
|
||||
containsLocation, err := bind.OptionalBool(r, "containsLocation", false)
|
||||
if err != nil {
|
||||
return app.OutlookFilter{}, err
|
||||
}
|
||||
filter.ContainsLocation = &containsLocation
|
||||
}
|
||||
|
||||
return filter, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user