diff --git a/cmd/forecast.go b/cmd/forecast.go index 371696d..f268578 100644 --- a/cmd/forecast.go +++ b/cmd/forecast.go @@ -7,10 +7,9 @@ import ( "time" "git.sr.ht/~timharek/yr/cmd/flags" + "git.sr.ht/~timharek/yr/cmd/internal/ui/table" "git.sr.ht/~timharek/yr/internal/nominatim" "git.sr.ht/~timharek/yr/yr" - "github.com/charmbracelet/lipgloss" - "github.com/charmbracelet/lipgloss/table" "github.com/pkg/browser" "github.com/spf13/cobra" ) @@ -76,33 +75,7 @@ func forecast(cmd *cobra.Command, args []string) { return } - re := lipgloss.NewRenderer(os.Stdout) - - const ( - white = lipgloss.Color("#fff") - lightGray = lipgloss.Color("#dedede") - ) - var ( - HeaderStyle = re.NewStyle().Foreground(white).Bold(true).Align(lipgloss.Center) - CellStyle = re.NewStyle().Padding(0, 2) - EvenRowStyle = CellStyle.Foreground(lightGray) - BorderStyle = lipgloss.NewStyle().Foreground(white) - ) - - t := table.New(). - Border(lipgloss.NormalBorder()). - BorderStyle(BorderStyle). - StyleFunc(func(row, col int) lipgloss.Style { - switch { - case row == 0: - return HeaderStyle - case row%2 == 0: - return EvenRowStyle - default: - return CellStyle - } - }). - Headers("time", "temp.", "rain", "wind") + t := table.New() for _, item := range f.Forecast { itemTime := item.Time.Local() @@ -115,8 +88,6 @@ func forecast(cmd *cobra.Command, args []string) { fmt.Sprintf("%.1f mm", item.Percipitation), fmt.Sprintf("%.1f m/s %s", item.Wind.Speed, item.Wind.DirectionToString()), ) - } - fmt.Println(t) } diff --git a/cmd/internal/ui/table/table.go b/cmd/internal/ui/table/table.go new file mode 100644 index 0000000..9cd4943 --- /dev/null +++ b/cmd/internal/ui/table/table.go @@ -0,0 +1,40 @@ +package table + +import ( + "os" + + "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/lipgloss/table" +) + +// TODO: Make more generic +func New() *table.Table { + re := lipgloss.NewRenderer(os.Stdout) + + const ( + white = lipgloss.Color("#fff") + lightGray = lipgloss.Color("#dedede") + ) + var ( + HeaderStyle = re.NewStyle().Foreground(white).Bold(true).Align(lipgloss.Center) + CellStyle = re.NewStyle().Padding(0, 2) + EvenRowStyle = CellStyle.Foreground(lightGray) + BorderStyle = lipgloss.NewStyle().Foreground(white) + ) + + t := table.New(). + Border(lipgloss.NormalBorder()). + BorderStyle(BorderStyle). + StyleFunc(func(row, col int) lipgloss.Style { + switch { + case row == 0: + return HeaderStyle + case row%2 == 0: + return EvenRowStyle + default: + return CellStyle + } + }). + Headers("time", "temp.", "rain", "wind") + return t +} diff --git a/cmd/tomorrow.go b/cmd/tomorrow.go new file mode 100644 index 0000000..6a69bec --- /dev/null +++ b/cmd/tomorrow.go @@ -0,0 +1,91 @@ +package cmd + +import ( + "encoding/json" + "fmt" + "os" + "time" + + "git.sr.ht/~timharek/yr/cmd/flags" + "git.sr.ht/~timharek/yr/cmd/internal/ui/table" + "git.sr.ht/~timharek/yr/internal/nominatim" + "git.sr.ht/~timharek/yr/yr" + "github.com/pkg/browser" + "github.com/spf13/cobra" +) + +var tomorrowCmd = &cobra.Command{ + Use: "tomorrow ", + Aliases: []string{"twm", "trm"}, + Short: "Get tomorrow's forecasted weather", + Args: cobra.MaximumNArgs(1), + Run: tomorrow, +} + +func init() { + rootCmd.AddCommand(tomorrowCmd) +} + +func tomorrow(cmd *cobra.Command, args []string) { + isJson, err := cmd.Flags().GetBool(flags.JSON) + cobra.CheckErr(err) + isUTC, err := cmd.Flags().GetBool(flags.UTC) + cobra.CheckErr(err) + isWeb, err := cmd.Flags().GetBool(flags.WEB) + cobra.CheckErr(err) + lon, _ := cmd.Flags().GetFloat64(flags.LON) + lat, _ := cmd.Flags().GetFloat64(flags.LAT) + + c, err := yr.New() + cobra.CheckErr(err) + + if len(args) == 0 && (lon == 0 || lat == 0) { + fmt.Fprintln(os.Stderr, "No location or coordinates provided.") + os.Exit(1) + } + f := &yr.ForecastResult{} + if len(args) == 0 { + f, err = c.ForecastCoords(&nominatim.Coordinates{Longitude: lon, Latitude: lat}, nil) + cobra.CheckErr(err) + } else { + location := args[0] + f, err = c.Forecast(location) + cobra.CheckErr(err) + } + + if isWeb { + url := fmt.Sprintf("https://www.yr.no/en/forecast/hourly-table/%.4f,%.4f?i=1", f.Coordinates.Latitude, f.Coordinates.Longitude) + err := browser.OpenURL(url) + if err != nil { + cobra.CheckErr(err) + } + os.Exit(0) + } + + if isJson { + j, err := json.MarshalIndent(f, "", " ") + cobra.CheckErr(err) + fmt.Printf("%s", j) + return + } + + t := table.New() + + tomorrow := time.Now().AddDate(0, 0, 1) + for _, item := range f.Forecast { + if item.Time.Format(time.DateOnly) != tomorrow.Format(time.DateOnly) { + continue + } + itemTime := item.Time.Local() + if isUTC { + itemTime = item.Time + } + t.Row( + fmt.Sprintf("tomorrow %s", itemTime.Format("15:04")), + fmt.Sprintf("%.1f °C", item.Temperature), + fmt.Sprintf("%.1f mm", item.Percipitation), + fmt.Sprintf("%.1f m/s %s", item.Wind.Speed, item.Wind.DirectionToString()), + ) + } + fmt.Println(t) +}