package briefing import ( "time" "gitea.maximumdirect.net/eric/weatherreporter/internal/module" "gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil" "gitea.maximumdirect.net/eric/weatherreporter/internal/weatherdata" ) type SPCConvectiveOutlooksModule struct { Checked bool `json:"checked"` AsOf string `json:"as_of,omitempty"` IssuedAt string `json:"issued_at,omitempty"` LocationID string `json:"location_id,omitempty"` LocationName string `json:"location_name,omitempty"` OutlookCount int `json:"outlook_count"` Outlooks []SPCConvectiveOutlookRecord `json:"outlooks,omitempty"` } type SPCConvectiveOutlookRecord struct { Day int `json:"day,omitempty"` OutlookType string `json:"outlook_type,omitempty"` Label string `json:"label,omitempty"` LabelText string `json:"label_text,omitempty"` PeriodBegins string `json:"period_begins,omitempty"` PeriodEnds string `json:"period_ends,omitempty"` IssuedAt string `json:"issued_at,omitempty"` ContainsLocation bool `json:"contains_location"` ImageURL string `json:"image_url,omitempty"` } func buildSPCConvectiveOutlooksModule(ctx ModuleContext, _ any) (*module.Output, error) { value := SPCConvectiveOutlooksModule{} run := ctx.Collected.SPCConvectiveOutlooks if run != nil { value.Checked = true value.AsOf = friendlyOptionalTime(run.AsOf, ctx.Timezone) value.IssuedAt = friendlyOptionalTime(run.IssuedAt, ctx.Timezone) value.LocationID = run.LocationID value.LocationName = run.LocationName } source, ok := sourceByName(ctx.Collected.SourceProvenance, string(module.SPCConvectiveOutlooks)) if value.Checked && value.AsOf == "" && ok && !source.FetchedAt.IsZero() { value.AsOf = friendlyDateTimeLabel(source.FetchedAt, ctx.Timezone) } if value.Checked && value.IssuedAt == "" && ok { value.IssuedAt = friendlyOptionalTime(source.IssuedAt, ctx.Timezone) } value.Outlooks = spcConvectiveOutlookRecords(ctx.Derived.SPCConvectiveOutlooks, ctx.Resolved.ValidPeriod, ctx.Timezone) value.OutlookCount = len(value.Outlooks) return &module.Output{ID: module.SPCConvectiveOutlooks, StanzaName: string(module.SPCConvectiveOutlooks), Value: value}, nil } func spcConvectiveOutlookRecords(outlooks []weatherdata.ConvectiveOutlook, reportPeriod timeutil.Period, timezone string) []SPCConvectiveOutlookRecord { records := make([]SPCConvectiveOutlookRecord, 0, len(outlooks)) for _, outlook := range outlooks { outlookPeriod := timeutil.Period{Start: outlook.ValidFrom, End: outlook.ValidTo} if !outlookPeriod.IsValid() || !outlookPeriod.Overlaps(reportPeriod) { continue } records = append(records, SPCConvectiveOutlookRecord{ Day: outlook.Day, OutlookType: outlook.OutlookType, Label: outlook.Label, LabelText: outlook.LabelText, PeriodBegins: friendlyPeriodBeginsLabel(outlookPeriod, timezone), PeriodEnds: friendlyPeriodEndsLabel(outlookPeriod, timezone), IssuedAt: friendlyOptionalTime(outlook.IssuedAt, timezone), ContainsLocation: outlook.ContainsLocation, ImageURL: outlook.ImageURL, }) } return records } func friendlyOptionalTime(value *time.Time, timezone string) string { if value == nil { return "" } return friendlyDateTimeLabel(*value, timezone) } func sourceByName(sources []weatherdata.Source, name string) (weatherdata.Source, bool) { for _, source := range sources { if source.Name == name { return source, true } } return weatherdata.Source{}, false }