95 lines
3.5 KiB
Go
95 lines
3.5 KiB
Go
package briefing
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/module"
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil"
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/weatherdata"
|
|
)
|
|
|
|
const defaultSPCConvectiveDiscussionMinimumSeverityRank = defaultSPCRiskDigestMinimumSeverityRank
|
|
const spcCategoricalOutlookType = defaultSPCRiskDigestOutlookType
|
|
|
|
type SPCConvectiveDiscussionModule struct {
|
|
IncludedBecause string `json:"included_because"`
|
|
Discussions []SPCConvectiveDiscussionRecord `json:"discussions"`
|
|
}
|
|
|
|
type SPCConvectiveDiscussionRecord struct {
|
|
Day int `json:"day,omitempty"`
|
|
PeriodBegins string `json:"period_begins,omitempty"`
|
|
PeriodEnds string `json:"period_ends,omitempty"`
|
|
Headline string `json:"headline,omitempty"`
|
|
Summary string `json:"summary,omitempty"`
|
|
Discussion string `json:"discussion,omitempty"`
|
|
UpdatedAt string `json:"updated_at,omitempty"`
|
|
}
|
|
|
|
func buildSPCConvectiveDiscussionModule(ctx ModuleContext, _ any) (*module.Output, error) {
|
|
qualifyingPeriods := spcConvectiveDiscussionQualifyingPeriods(ctx.Derived.SPCConvectiveOutlooks, ctx.Resolved.ValidPeriod)
|
|
if len(qualifyingPeriods) == 0 {
|
|
return nil, nil
|
|
}
|
|
records := spcConvectiveDiscussionRecords(qualifyingPeriods, ctx.Derived.SPCConvectiveDiscussions, ctx.Timezone)
|
|
if len(records) == 0 {
|
|
return nil, nil
|
|
}
|
|
value := SPCConvectiveDiscussionModule{
|
|
IncludedBecause: fmt.Sprintf("%s severity_rank >= %d", spcCategoricalOutlookType, defaultSPCConvectiveDiscussionMinimumSeverityRank),
|
|
Discussions: records,
|
|
}
|
|
return &module.Output{ID: module.SPCConvectiveDiscussion, StanzaName: string(module.SPCConvectiveDiscussion), Value: value}, nil
|
|
}
|
|
|
|
func spcConvectiveDiscussionQualifyingPeriods(outlooks []weatherdata.ConvectiveOutlook, reportPeriod timeutil.Period) map[int]timeutil.Period {
|
|
periods := map[int]timeutil.Period{}
|
|
for _, outlook := range outlooks {
|
|
if outlook.OutlookType != spcCategoricalOutlookType {
|
|
continue
|
|
}
|
|
if outlook.SeverityRank == nil || *outlook.SeverityRank < defaultSPCConvectiveDiscussionMinimumSeverityRank {
|
|
continue
|
|
}
|
|
outlookPeriod := timeutil.Period{Start: outlook.ValidFrom, End: outlook.ValidTo}
|
|
if !outlookPeriod.IsValid() || !outlookPeriod.Overlaps(reportPeriod) {
|
|
continue
|
|
}
|
|
if existing, ok := periods[outlook.Day]; ok {
|
|
if outlookPeriod.Start.Before(existing.Start) {
|
|
existing.Start = outlookPeriod.Start
|
|
}
|
|
if outlookPeriod.End.After(existing.End) {
|
|
existing.End = outlookPeriod.End
|
|
}
|
|
periods[outlook.Day] = existing
|
|
continue
|
|
}
|
|
periods[outlook.Day] = outlookPeriod
|
|
}
|
|
return periods
|
|
}
|
|
|
|
func spcConvectiveDiscussionRecords(qualifyingPeriods map[int]timeutil.Period, discussions []weatherdata.ConvectiveOutlookDiscussion, timezone string) []SPCConvectiveDiscussionRecord {
|
|
records := make([]SPCConvectiveDiscussionRecord, 0, len(discussions))
|
|
for _, discussion := range discussions {
|
|
period, ok := qualifyingPeriods[discussion.Day]
|
|
if !ok {
|
|
continue
|
|
}
|
|
if discussion.Discussion == "" {
|
|
continue
|
|
}
|
|
records = append(records, SPCConvectiveDiscussionRecord{
|
|
Day: discussion.Day,
|
|
PeriodBegins: friendlyPeriodBeginsLabel(period, timezone),
|
|
PeriodEnds: friendlyPeriodEndsLabel(period, timezone),
|
|
Headline: discussion.Headline,
|
|
Summary: discussion.Summary,
|
|
Discussion: discussion.Discussion,
|
|
UpdatedAt: friendlyOptionalTime(discussion.UpdatedAt, timezone),
|
|
})
|
|
}
|
|
return records
|
|
}
|