Added support for Area Forecast Discussions issued by the NWS
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:
72
internal/normalizers/nws/forecast_discussion.go
Normal file
72
internal/normalizers/nws/forecast_discussion.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package nws
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gitea.maximumdirect.net/ejr/feedkit/event"
|
||||
normcommon "gitea.maximumdirect.net/ejr/weatherfeeder/internal/normalizers/common"
|
||||
nwscommon "gitea.maximumdirect.net/ejr/weatherfeeder/internal/providers/nws"
|
||||
"gitea.maximumdirect.net/ejr/weatherfeeder/model"
|
||||
"gitea.maximumdirect.net/ejr/weatherfeeder/standards"
|
||||
)
|
||||
|
||||
type ForecastDiscussionNormalizer struct{}
|
||||
|
||||
func (ForecastDiscussionNormalizer) Match(e event.Event) bool {
|
||||
return strings.TrimSpace(e.Schema) == standards.SchemaRawNWSForecastDiscussionV1
|
||||
}
|
||||
|
||||
func (ForecastDiscussionNormalizer) Normalize(ctx context.Context, in event.Event) (*event.Event, error) {
|
||||
_ = ctx
|
||||
|
||||
rawHTML, err := decodeStringPayload(in.Payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("nws forecast discussion normalize: %w", err)
|
||||
}
|
||||
|
||||
parsed, err := nwscommon.ParseForecastDiscussionHTML(rawHTML)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("nws forecast discussion normalize: build: %w", err)
|
||||
}
|
||||
|
||||
payload := model.WeatherForecastDiscussion{
|
||||
OfficeID: strings.TrimSpace(parsed.OfficeID),
|
||||
OfficeName: strings.TrimSpace(parsed.OfficeName),
|
||||
Product: model.ForecastDiscussionProduct(strings.TrimSpace(parsed.Product)),
|
||||
IssuedAt: parsed.IssuedAt.UTC(),
|
||||
UpdatedAt: parsed.UpdatedAt,
|
||||
KeyMessages: append([]string(nil), parsed.KeyMessages...),
|
||||
ShortTerm: mapForecastDiscussionSection(parsed.ShortTerm),
|
||||
LongTerm: mapForecastDiscussionSection(parsed.LongTerm),
|
||||
}
|
||||
|
||||
out, err := normcommon.Finalize(in, standards.SchemaWeatherForecastDiscussionV1, payload, payload.IssuedAt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("nws forecast discussion normalize: %w", err)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func mapForecastDiscussionSection(in *nwscommon.ForecastDiscussionSection) *model.WeatherForecastDiscussionSection {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
return &model.WeatherForecastDiscussionSection{
|
||||
Qualifier: strings.TrimSpace(in.Qualifier),
|
||||
IssuedAt: in.IssuedAt,
|
||||
Text: strings.TrimSpace(in.Text),
|
||||
}
|
||||
}
|
||||
|
||||
func decodeStringPayload(payload any) (string, error) {
|
||||
switch v := payload.(type) {
|
||||
case string:
|
||||
return v, nil
|
||||
case []byte:
|
||||
return string(v), nil
|
||||
default:
|
||||
return "", fmt.Errorf("extract payload: expected string payload, got %T", payload)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user