162 lines
5.5 KiB
Go
162 lines
5.5 KiB
Go
package generatedtext
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/briefing"
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/facts"
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/module"
|
|
"gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil"
|
|
)
|
|
|
|
type HourlyRenderContext struct {
|
|
Report HourlyReportContext
|
|
GeneratedText Hourly
|
|
Modules HourlyTemplateModules
|
|
Collected facts.CollectedFacts
|
|
Derived facts.DerivedFacts
|
|
}
|
|
|
|
type HourlyReportContext struct {
|
|
Title string
|
|
LocationName string
|
|
GeneratedAt time.Time
|
|
GeneratedAtLabel string
|
|
ValidPeriod timeutil.Period
|
|
ValidPeriodLabel string
|
|
Timezone string
|
|
}
|
|
|
|
type HourlyTemplateModules struct {
|
|
Metadata *briefing.MetadataModule
|
|
CurrentConditions *briefing.CurrentConditionsModule
|
|
HourlyForecast *briefing.HourlyForecastModule
|
|
PrecipTiming *briefing.PrecipTimingModule
|
|
AlertDigest *briefing.AlertDigestModule
|
|
SPCConvectiveOutlooks *briefing.SPCConvectiveOutlooksModule
|
|
AreaForecastDiscussion *briefing.AreaForecastDiscussionModule
|
|
SPCConvectiveDiscussion *briefing.SPCConvectiveDiscussionModule
|
|
WeatherStory *briefing.WeatherStoryModule
|
|
}
|
|
|
|
func BuildHourlyRenderContext(metadata briefing.Metadata, snapshot module.Snapshot, generated Hourly, collected facts.CollectedFacts, derived facts.DerivedFacts) (HourlyRenderContext, error) {
|
|
location, err := timeutil.LoadLocation(metadata.Timezone)
|
|
if err != nil {
|
|
return HourlyRenderContext{}, fmt.Errorf("build hourly render context: %w", err)
|
|
}
|
|
if metadata.GeneratedAt.IsZero() {
|
|
return HourlyRenderContext{}, fmt.Errorf("build hourly render context: generatedAt is required")
|
|
}
|
|
if !metadata.ValidPeriod.IsValid() {
|
|
return HourlyRenderContext{}, fmt.Errorf("build hourly render context: valid period is required")
|
|
}
|
|
modules, err := hourlyTemplateModules(snapshot)
|
|
if err != nil {
|
|
return HourlyRenderContext{}, err
|
|
}
|
|
return HourlyRenderContext{
|
|
Report: HourlyReportContext{
|
|
Title: "Hourly Report",
|
|
LocationName: locationName(metadata),
|
|
GeneratedAt: metadata.GeneratedAt,
|
|
GeneratedAtLabel: timeLabel(metadata.GeneratedAt, location),
|
|
ValidPeriod: metadata.ValidPeriod,
|
|
ValidPeriodLabel: periodLabel(metadata.ValidPeriod, location),
|
|
Timezone: metadata.Timezone,
|
|
},
|
|
GeneratedText: generated,
|
|
Modules: modules,
|
|
Collected: collected,
|
|
Derived: derived,
|
|
}, nil
|
|
}
|
|
|
|
func hourlyTemplateModules(snapshot module.Snapshot) (HourlyTemplateModules, error) {
|
|
metadata, err := optionalStanza[briefing.MetadataModule](snapshot, string(module.Metadata))
|
|
if err != nil {
|
|
return HourlyTemplateModules{}, err
|
|
}
|
|
current, err := optionalStanza[briefing.CurrentConditionsModule](snapshot, string(module.CurrentConditions))
|
|
if err != nil {
|
|
return HourlyTemplateModules{}, err
|
|
}
|
|
hourly, err := optionalStanza[briefing.HourlyForecastModule](snapshot, string(module.HourlyForecast))
|
|
if err != nil {
|
|
return HourlyTemplateModules{}, err
|
|
}
|
|
precip, err := optionalStanza[briefing.PrecipTimingModule](snapshot, string(module.PrecipTiming))
|
|
if err != nil {
|
|
return HourlyTemplateModules{}, err
|
|
}
|
|
alerts, err := optionalStanza[briefing.AlertDigestModule](snapshot, string(module.AlertDigest))
|
|
if err != nil {
|
|
return HourlyTemplateModules{}, err
|
|
}
|
|
outlooks, err := optionalStanza[briefing.SPCConvectiveOutlooksModule](snapshot, string(module.SPCConvectiveOutlooks))
|
|
if err != nil {
|
|
return HourlyTemplateModules{}, err
|
|
}
|
|
discussion, err := optionalStanza[briefing.AreaForecastDiscussionModule](snapshot, string(module.AreaForecastDiscussion))
|
|
if err != nil {
|
|
return HourlyTemplateModules{}, err
|
|
}
|
|
spcDiscussion, err := optionalStanza[briefing.SPCConvectiveDiscussionModule](snapshot, string(module.SPCConvectiveDiscussion))
|
|
if err != nil {
|
|
return HourlyTemplateModules{}, err
|
|
}
|
|
story, err := optionalStanza[briefing.WeatherStoryModule](snapshot, string(module.WeatherStory))
|
|
if err != nil {
|
|
return HourlyTemplateModules{}, err
|
|
}
|
|
return HourlyTemplateModules{
|
|
Metadata: metadata,
|
|
CurrentConditions: current,
|
|
HourlyForecast: hourly,
|
|
PrecipTiming: precip,
|
|
AlertDigest: alerts,
|
|
SPCConvectiveOutlooks: outlooks,
|
|
AreaForecastDiscussion: discussion,
|
|
SPCConvectiveDiscussion: spcDiscussion,
|
|
WeatherStory: story,
|
|
}, nil
|
|
}
|
|
|
|
func optionalStanza[T any](snapshot module.Snapshot, name string) (*T, error) {
|
|
output, ok := snapshot.LookupStanza(name)
|
|
if !ok || output.Value == nil {
|
|
return nil, nil
|
|
}
|
|
value, _, err := module.StanzaValue[T](snapshot, name)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("build hourly render context: %w", err)
|
|
}
|
|
return &value, nil
|
|
}
|
|
|
|
func locationName(metadata briefing.Metadata) string {
|
|
if metadata.Location != nil {
|
|
if metadata.Location.Name != "" && metadata.Location.Region != "" {
|
|
return metadata.Location.Name + ", " + metadata.Location.Region
|
|
}
|
|
if metadata.Location.Name != "" {
|
|
return metadata.Location.Name
|
|
}
|
|
}
|
|
if metadata.SourceLocation != "" {
|
|
return metadata.SourceLocation
|
|
}
|
|
if metadata.SourceLocationID != "" {
|
|
return metadata.SourceLocationID
|
|
}
|
|
return "Unknown location"
|
|
}
|
|
|
|
func periodLabel(period timeutil.Period, location *time.Location) string {
|
|
return fmt.Sprintf("%s to %s", timeLabel(period.Start, location), timeLabel(period.End, location))
|
|
}
|
|
|
|
func timeLabel(value time.Time, location *time.Location) string {
|
|
return value.In(location).Format("2006-01-02 at 3:04 PM")
|
|
}
|