feat: Add flag for opening result in web-browser

Signed-off-by: Tim Hårek Andreassen <tim@harek.no>
This commit is contained in:
Tim Hårek Andreassen 2024-10-03 16:05:18 +02:00
parent a638c0b678
commit 10e1c770af
No known key found for this signature in database
GPG key ID: E59C7734F0E10EB5
8 changed files with 62 additions and 16 deletions

View file

@ -6,4 +6,5 @@ const (
JSON = "json" JSON = "json"
INTERVAL = "interval" INTERVAL = "interval"
UTC = "utc" UTC = "utc"
WEB = "web"
) )

View file

@ -11,6 +11,7 @@ import (
"git.sr.ht/~timharek/yr-go/yr" "git.sr.ht/~timharek/yr-go/yr"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/table" "github.com/charmbracelet/lipgloss/table"
"github.com/pkg/browser"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -32,6 +33,8 @@ func forecast(cmd *cobra.Command, args []string) {
cobra.CheckErr(err) cobra.CheckErr(err)
isUTC, err := cmd.Flags().GetBool(flags.UTC) isUTC, err := cmd.Flags().GetBool(flags.UTC)
cobra.CheckErr(err) cobra.CheckErr(err)
isWeb, err := cmd.Flags().GetBool(flags.WEB)
cobra.CheckErr(err)
lon, _ := cmd.Flags().GetFloat64(flags.LON) lon, _ := cmd.Flags().GetFloat64(flags.LON)
lat, _ := cmd.Flags().GetFloat64(flags.LAT) lat, _ := cmd.Flags().GetFloat64(flags.LAT)
interval, _ := cmd.Flags().GetInt(flags.INTERVAL) interval, _ := cmd.Flags().GetInt(flags.INTERVAL)
@ -43,7 +46,7 @@ func forecast(cmd *cobra.Command, args []string) {
fmt.Fprintln(os.Stderr, "No location or coordinates provided.") fmt.Fprintln(os.Stderr, "No location or coordinates provided.")
os.Exit(1) os.Exit(1)
} }
var f []yr.Forecast f := &yr.ForecastResult{}
if len(args) == 0 { if len(args) == 0 {
f, err = c.ForecastCoords(&nominatim.Coordinates{Longitude: lon, Latitude: lat}, nil) f, err = c.ForecastCoords(&nominatim.Coordinates{Longitude: lon, Latitude: lat}, nil)
cobra.CheckErr(err) cobra.CheckErr(err)
@ -53,8 +56,17 @@ func forecast(cmd *cobra.Command, args []string) {
cobra.CheckErr(err) cobra.CheckErr(err)
} }
if isWeb {
url := fmt.Sprintf("https://www.yr.no/en/forecast/daily-table/%.4f,%.4f", f.Coordinates.Latitude, f.Coordinates.Longitude)
err := browser.OpenURL(url)
if err != nil {
cobra.CheckErr(err)
}
os.Exit(0)
}
if interval > 0 { if interval > 0 {
f = f[:interval] f.Forecast = f.Forecast[:interval]
} }
if isJson { if isJson {
@ -92,7 +104,7 @@ func forecast(cmd *cobra.Command, args []string) {
}). }).
Headers("time", "temp.", "rain", "wind") Headers("time", "temp.", "rain", "wind")
for _, item := range f { for _, item := range f.Forecast {
itemTime := item.Time.Local() itemTime := item.Time.Local()
if isUTC { if isUTC {
itemTime = item.Time itemTime = item.Time

View file

@ -9,6 +9,7 @@ import (
"git.sr.ht/~timharek/yr-go/cmd/flags" "git.sr.ht/~timharek/yr-go/cmd/flags"
"git.sr.ht/~timharek/yr-go/internal/nominatim" "git.sr.ht/~timharek/yr-go/internal/nominatim"
"git.sr.ht/~timharek/yr-go/yr" "git.sr.ht/~timharek/yr-go/yr"
"github.com/pkg/browser"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -29,6 +30,8 @@ func now(cmd *cobra.Command, args []string) {
cobra.CheckErr(err) cobra.CheckErr(err)
isUTC, err := cmd.Flags().GetBool(flags.UTC) isUTC, err := cmd.Flags().GetBool(flags.UTC)
cobra.CheckErr(err) cobra.CheckErr(err)
isWeb, err := cmd.Flags().GetBool(flags.WEB)
cobra.CheckErr(err)
lon, _ := cmd.Flags().GetFloat64(flags.LON) lon, _ := cmd.Flags().GetFloat64(flags.LON)
lat, _ := cmd.Flags().GetFloat64(flags.LAT) lat, _ := cmd.Flags().GetFloat64(flags.LAT)
@ -39,20 +42,31 @@ func now(cmd *cobra.Command, args []string) {
fmt.Fprintln(os.Stderr, "No location or coordinates provided.") fmt.Fprintln(os.Stderr, "No location or coordinates provided.")
os.Exit(1) os.Exit(1)
} }
n := &yr.Forecast{} f := &yr.ForecastResult{}
if len(args) == 0 { if len(args) == 0 {
n, err = c.NowCoords(&nominatim.Coordinates{Longitude: lon, Latitude: lat}, nil) f, err = c.NowCoords(&nominatim.Coordinates{Longitude: lon, Latitude: lat}, nil)
cobra.CheckErr(err) cobra.CheckErr(err)
} else { } else {
location := args[0] location := args[0]
n, err = c.Now(location) f, err = c.Now(location)
cobra.CheckErr(err) cobra.CheckErr(err)
} }
if isWeb {
url := fmt.Sprintf("https://www.yr.no/en/forecast/hourly-table/%.4f,%.4f/?i=0", f.Coordinates.Latitude, f.Coordinates.Longitude)
err := browser.OpenURL(url)
if err != nil {
cobra.CheckErr(err)
}
os.Exit(0)
}
n := f.Forecast[0]
if isJson { if isJson {
j, err := json.MarshalIndent(n, "", " ") j, err := json.MarshalIndent(f, "", " ")
cobra.CheckErr(err) cobra.CheckErr(err)
fmt.Printf("%s", j) fmt.Printf("%s", j)
return return

View file

@ -23,6 +23,7 @@ func Execute() {
func init() { func init() {
rootCmd.PersistentFlags().Bool(flags.JSON, false, "Result in JSON") rootCmd.PersistentFlags().Bool(flags.JSON, false, "Result in JSON")
rootCmd.PersistentFlags().Bool(flags.UTC, false, "Result times in UTC") rootCmd.PersistentFlags().Bool(flags.UTC, false, "Result times in UTC")
rootCmd.PersistentFlags().Bool(flags.WEB, false, "Open result in browser")
rootCmd.PersistentFlags().Float64P(flags.LON, "x", 0, "Longitude coordinate") rootCmd.PersistentFlags().Float64P(flags.LON, "x", 0, "Longitude coordinate")
rootCmd.PersistentFlags().Float64P(flags.LAT, "y", 0, "Latitude coordinate") rootCmd.PersistentFlags().Float64P(flags.LAT, "y", 0, "Latitude coordinate")
} }

3
go.mod
View file

@ -3,13 +3,14 @@ module git.sr.ht/~timharek/yr-go
go 1.23.1 go 1.23.1
require ( require (
github.com/charmbracelet/lipgloss v0.13.0
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
) )
require ( require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/lipgloss v0.13.0 // indirect
github.com/charmbracelet/x/ansi v0.1.4 // indirect github.com/charmbracelet/x/ansi v0.1.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect

3
go.sum
View file

@ -25,6 +25,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@ -41,6 +43,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

View file

@ -12,3 +12,6 @@ test:
tidy: tidy:
go mod tidy go mod tidy
vet:
go vet ./...

View file

@ -73,7 +73,12 @@ type Forecast struct {
Wind wind `json:"wind"` // In m/s Wind wind `json:"wind"` // In m/s
} }
func (c *Client) Now(q string) (*Forecast, error) { type ForecastResult struct {
Coordinates nominatim.Coordinates `json:"coordinates"`
Forecast []Forecast `json:"forecast"`
}
func (c *Client) Now(q string) (*ForecastResult, error) {
coords, err := c.nom.Lookup(q) coords, err := c.nom.Lookup(q)
if err != nil { if err != nil {
return nil, err return nil, err
@ -85,18 +90,18 @@ func (c *Client) Now(q string) (*Forecast, error) {
}, &coords.Location) }, &coords.Location)
} }
func (c *Client) NowCoords(coords *nominatim.Coordinates, location *string) (*Forecast, error) { func (c *Client) NowCoords(coords *nominatim.Coordinates, location *string) (*ForecastResult, error) {
forecasts, err := c.ForecastCoords(coords, location) result, err := c.ForecastCoords(coords, location)
if err != nil { if err != nil {
return nil, err return nil, err
} }
now := forecasts[0] result.Forecast = result.Forecast[0:]
return &now, nil return result, nil
} }
func (c *Client) Forecast(q string) ([]Forecast, error) { func (c *Client) Forecast(q string) (*ForecastResult, error) {
coords, err := c.nom.Lookup(q) coords, err := c.nom.Lookup(q)
if err != nil { if err != nil {
return nil, err return nil, err
@ -108,7 +113,7 @@ func (c *Client) Forecast(q string) ([]Forecast, error) {
}, &coords.Location) }, &coords.Location)
} }
func (c *Client) ForecastCoords(coords *nominatim.Coordinates, location *string) ([]Forecast, error) { func (c *Client) ForecastCoords(coords *nominatim.Coordinates, location *string) (*ForecastResult, error) {
f, err := c.met.Forecast(coords.Latitude, coords.Longitude, nil) f, err := c.met.Forecast(coords.Latitude, coords.Longitude, nil)
if err != nil { if err != nil {
return nil, err return nil, err
@ -168,7 +173,13 @@ func (c *Client) ForecastCoords(coords *nominatim.Coordinates, location *string)
} }
return forecasts, nil return &ForecastResult{
Coordinates: nominatim.Coordinates{
Longitude: coords.Longitude,
Latitude: coords.Latitude,
},
Forecast: forecasts,
}, nil
} }
func sortTimeSeries(a, b met.Timeseries) int { func sortTimeSeries(a, b met.Timeseries) int {