diff --git a/cmd/openweather/handler.go b/cmd/openweather/handler.go new file mode 100644 index 0000000..43aed26 --- /dev/null +++ b/cmd/openweather/handler.go @@ -0,0 +1,86 @@ +package main + +import ( + "context" + "encoding/json" + "log" + "time" + + "github.com/neatflowcv/seven-skies/internal/pkg/broker" + "github.com/neatflowcv/seven-skies/internal/pkg/domain" + "github.com/neatflowcv/seven-skies/internal/pkg/openweather" +) + +type Handler struct { + broker broker.Broker + key string + lat float64 + lon float64 +} + +func NewHandler(broker broker.Broker, key string, lat float64, lon float64) *Handler { + return &Handler{ + broker: broker, + key: key, + lat: lat, + lon: lon, + } +} + +func (h *Handler) Handle(ctx context.Context) error { + log.Println("get forecast") + + forecast, err := openweather.Forecast(ctx, h.key, h.lat, h.lon) + if err != nil { + log.Println("error in get forecast", err) + + return err + } + + log.Println("get forecast successfully", forecast) + + for _, list := range forecast.List { + weatherEvent := domain.WeatherEvent{ + Date: time.Unix(int64(list.Dt), 0), + Condition: decideCondition(list.Weather[0].Main), + Temperature: &domain.Temperature{Value: domain.Celsius(list.Main.Temp)}, + High: &domain.Temperature{Value: domain.Celsius(list.Main.TempMax)}, + Low: &domain.Temperature{Value: domain.Celsius(list.Main.TempMin)}, + } + + message, err := json.Marshal(weatherEvent) + if err != nil { + log.Println("error in marshal weather event", err) + + continue + } + + err = h.broker.Publish(ctx, "SEVEN_SKIES_SUBJECT.OPENWEATHER", message) + if err != nil { + log.Println("error in publish weather event", err) + + continue + } + } + + return nil +} + +func decideCondition(main string) domain.WeatherCondition { + switch main { + case "Thunderstorm", "Drizzle", "Rain": + return domain.WeatherConditionRain + + case "Snow": + return domain.WeatherConditionSnow + + case "Mist", "Smoke", "Haze", "Dust", "Fog", "Sand", "Ash", "Squall", "Tornado", "Clouds": + return domain.WeatherConditionCloudy + + case "Clear": + return domain.WeatherConditionClear + + default: + return domain.WeatherConditionUnknown + } +} diff --git a/cmd/openweather/main.go b/cmd/openweather/main.go index 25ddaea..07a0745 100644 --- a/cmd/openweather/main.go +++ b/cmd/openweather/main.go @@ -2,19 +2,14 @@ package main import ( "context" - "encoding/json" "log" "os" "runtime/debug" "strconv" - "time" "github.com/go-co-op/gocron/v2" "github.com/joho/godotenv" - "github.com/neatflowcv/seven-skies/internal/pkg/broker" "github.com/neatflowcv/seven-skies/internal/pkg/broker/nats" - "github.com/neatflowcv/seven-skies/internal/pkg/domain" - "github.com/neatflowcv/seven-skies/internal/pkg/openweather" ) func version() string { @@ -88,6 +83,8 @@ func main() { } defer broker.Close() + handler := NewHandler(broker, config.Key, config.Lat, config.Lon) + scheduler, err := gocron.NewScheduler() if err != nil { log.Panic("error in create scheduler", err) @@ -100,7 +97,7 @@ func main() { } }() - err = Task(context.Background(), broker, config.Key, config.Lat, config.Lon) + err = handler.Handle(context.Background()) if err != nil { log.Panic("error in task", err) } @@ -109,12 +106,7 @@ func main() { gocron.CronJob("5 */2 * * *", false), // openweather에서 2시간마다 데이터가 업데이트 된다. // 5분을 준 이유는 업데이트가 바로 된다는 보장이 없어서 gocron.NewTask( - Task, - context.Background(), - broker, - config.Key, - config.Lat, - config.Lon, + handler.Handle, ), ) if err != nil { @@ -132,61 +124,3 @@ func main() { select {} } - -func Task(ctx context.Context, broker broker.Broker, key string, lat float64, lon float64) error { - log.Println("get forecast") - - forecast, err := openweather.Forecast(context.Background(), key, lat, lon) - if err != nil { - log.Println("error in get forecast", err) - - return err - } - - log.Println("get forecast successfully", forecast) - - for _, list := range forecast.List { - weatherEvent := domain.WeatherEvent{ - Date: time.Unix(int64(list.Dt), 0), - Condition: decideCondition(list.Weather[0].Main), - Temperature: &domain.Temperature{Value: domain.Celsius(list.Main.Temp)}, - High: &domain.Temperature{Value: domain.Celsius(list.Main.TempMax)}, - Low: &domain.Temperature{Value: domain.Celsius(list.Main.TempMin)}, - } - - message, err := json.Marshal(weatherEvent) - if err != nil { - log.Println("error in marshal weather event", err) - - continue - } - - err = broker.Publish(ctx, "SEVEN_SKIES_SUBJECT.OPENWEATHER", message) - if err != nil { - log.Println("error in publish weather event", err) - - continue - } - } - - return nil -} - -func decideCondition(main string) domain.WeatherCondition { - switch main { - case "Thunderstorm", "Drizzle", "Rain": - return domain.WeatherConditionRain - - case "Snow": - return domain.WeatherConditionSnow - - case "Mist", "Smoke", "Haze", "Dust", "Fog", "Sand", "Ash", "Squall", "Tornado", "Clouds": - return domain.WeatherConditionCloudy - - case "Clear": - return domain.WeatherConditionClear - - default: - return domain.WeatherConditionUnknown - } -}