Added support for /forecast/hourly/today and /forecast/hourly/tomorrow endpoints
All checks were successful
ci/woodpecker/push/build-image Pipeline was successful
All checks were successful
ci/woodpecker/push/build-image Pipeline was successful
This commit is contained in:
@@ -4,25 +4,81 @@ package httpapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"gitea.maximumdirect.net/ejr/feedapi/endpoint"
|
||||
"gitea.maximumdirect.net/ejr/feedapi/render"
|
||||
"gitea.maximumdirect.net/ejr/feedapi/response"
|
||||
"gitea.maximumdirect.net/ejr/weatherapi/internal/adapters/inbound/httpapi/presenter"
|
||||
"gitea.maximumdirect.net/ejr/weatherfeeder/model"
|
||||
)
|
||||
|
||||
func forecastDefinition(svc Service) endpoint.Definition {
|
||||
type forecastDaySlice int
|
||||
|
||||
const (
|
||||
forecastDaySliceAll forecastDaySlice = iota
|
||||
forecastDaySliceToday
|
||||
forecastDaySliceTomorrow
|
||||
)
|
||||
|
||||
var forecastNow = time.Now
|
||||
|
||||
func forecastDefinitions(svc Service) []endpoint.Definition {
|
||||
return []endpoint.Definition{
|
||||
forecastDefinition(svc, "/forecast/hourly", forecastDaySliceAll),
|
||||
forecastDefinition(svc, "/forecast/hourly/today", forecastDaySliceToday),
|
||||
forecastDefinition(svc, "/forecast/hourly/tomorrow", forecastDaySliceTomorrow),
|
||||
}
|
||||
}
|
||||
|
||||
func forecastDefinition(svc Service, path string, daySlice forecastDaySlice) endpoint.Definition {
|
||||
return endpoint.GET(
|
||||
"/forecast/hourly",
|
||||
path,
|
||||
bindForecastPrecisionQuery,
|
||||
func(ctx context.Context, req precisionQueryRequest) (any, error) {
|
||||
run, err := svc.LatestHourlyForecast(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if daySlice != forecastDaySliceAll {
|
||||
run = filterForecastRunByDaySlice(run, req.Timezone, daySlice)
|
||||
}
|
||||
|
||||
return response.Envelope{Data: presenter.ForecastPayload(run, req.Units, req.Precision, req.Timezone)}, nil
|
||||
},
|
||||
endpoint.WithProduces(render.FormatJSON, render.FormatXML, render.FormatText),
|
||||
endpoint.WithTemplate("forecast_hourly.txt.tmpl"),
|
||||
)
|
||||
}
|
||||
|
||||
func filterForecastRunByDaySlice(run *model.WeatherForecastRun, tz *time.Location, daySlice forecastDaySlice) *model.WeatherForecastRun {
|
||||
if run == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
loc := tz
|
||||
if loc == nil {
|
||||
loc = time.UTC
|
||||
}
|
||||
|
||||
now := forecastNow().In(loc)
|
||||
target := now
|
||||
if daySlice == forecastDaySliceTomorrow {
|
||||
target = target.AddDate(0, 0, 1)
|
||||
}
|
||||
year, month, day := target.Date()
|
||||
|
||||
periods := make([]model.WeatherForecastPeriod, 0, len(run.Periods))
|
||||
for _, period := range run.Periods {
|
||||
start := period.StartTime.In(loc)
|
||||
y, m, d := start.Date()
|
||||
if y == year && m == month && d == day {
|
||||
periods = append(periods, period)
|
||||
}
|
||||
}
|
||||
|
||||
cloned := *run
|
||||
cloned.Periods = periods
|
||||
return &cloned
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user