docs: Add docs
Signed-off-by: Tim Hårek Andreassen <tim@harek.no>
This commit is contained in:
parent
7435512ffb
commit
97e085e2ad
6 changed files with 31 additions and 8 deletions
1
main.go
1
main.go
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import "git.sr.ht/~timharek/yr/cmd"
|
import "git.sr.ht/~timharek/yr/cmd"
|
||||||
|
|
||||||
|
// Execute CLI
|
||||||
func main() {
|
func main() {
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
}
|
}
|
||||||
|
|
1
pkg/cache/cache.go
vendored
1
pkg/cache/cache.go
vendored
|
@ -14,6 +14,7 @@ type Cache[T any] struct {
|
||||||
Path string
|
Path string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New Cache where default path is os.TempDir()
|
||||||
func New[T any](path string) *Cache[T] {
|
func New[T any](path string) *Cache[T] {
|
||||||
if path == "" {
|
if path == "" {
|
||||||
path = os.TempDir()
|
path = os.TempDir()
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Access [Meteorologisk institutt's API](https://api.met.no)
|
||||||
package met
|
package met
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -12,6 +13,7 @@ type Met struct {
|
||||||
siteName string
|
siteName string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns valid Met client or error if empty siteName is provided
|
||||||
func New(siteName string) (*Met, error) {
|
func New(siteName string) (*Met, error) {
|
||||||
if siteName == "" {
|
if siteName == "" {
|
||||||
return nil, fmt.Errorf("`siteName` must be defined.")
|
return nil, fmt.Errorf("`siteName` must be defined.")
|
||||||
|
@ -22,6 +24,8 @@ func New(siteName string) (*Met, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get LocationForecast from Met, returns error if Met doesn't answer or response is missing required headers
|
||||||
|
// API endpoint: https://api.met.no/weatherapi/locationforecast/2.0/documentation
|
||||||
func (m *Met) Forecast(lat, lon float64, alt *int) (*LocationForecastResult, error) {
|
func (m *Met) Forecast(lat, lon float64, alt *int) (*LocationForecastResult, error) {
|
||||||
url := "https://api.met.no/weatherapi/locationforecast/2.0/complete"
|
url := "https://api.met.no/weatherapi/locationforecast/2.0/complete"
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ func New(siteName string) (*Nominatim, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search for coordinates based on q
|
||||||
|
// API endpoint: https://nominatim.openstreetmap.org/search
|
||||||
func (n *Nominatim) Search(q string) (*SearchResults, error) {
|
func (n *Nominatim) Search(q string) (*SearchResults, error) {
|
||||||
url := fmt.Sprintf("https://nominatim.openstreetmap.org/search?q=%s&format=jsonv2", url.QueryEscape(q))
|
url := fmt.Sprintf("https://nominatim.openstreetmap.org/search?q=%s&format=jsonv2", url.QueryEscape(q))
|
||||||
|
|
||||||
|
@ -58,6 +60,8 @@ func (n *Nominatim) Search(q string) (*SearchResults, error) {
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reverse search for location based on lat and lon
|
||||||
|
// API endpoint: https://nominatim.openstreetmap.org/reverse
|
||||||
func (n *Nominatim) Reverse(lat, lon float64) (*ReverseResult, error) {
|
func (n *Nominatim) Reverse(lat, lon float64) (*ReverseResult, error) {
|
||||||
url := fmt.Sprintf("https://nominatim.openstreetmap.org/reverse?lat=%.16f&lon=%.16f&format=jsonv2", lat, lon)
|
url := fmt.Sprintf("https://nominatim.openstreetmap.org/reverse?lat=%.16f&lon=%.16f&format=jsonv2", lat, lon)
|
||||||
|
|
||||||
|
@ -101,6 +105,7 @@ type LookupResult struct {
|
||||||
Location string `json:"location"`
|
Location string `json:"location"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lookup location coordinates based on q
|
||||||
func (n *Nominatim) Lookup(q string) (*LookupResult, error) {
|
func (n *Nominatim) Lookup(q string) (*LookupResult, error) {
|
||||||
r, err := n.Search(q)
|
r, err := n.Search(q)
|
||||||
|
|
||||||
|
@ -132,6 +137,7 @@ func (n *Nominatim) Lookup(q string) (*LookupResult, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lookup location name based on lat and lon
|
||||||
func (n *Nominatim) ReverseLookup(lat, lon float64) (*LookupResult, error) {
|
func (n *Nominatim) ReverseLookup(lat, lon float64) (*LookupResult, error) {
|
||||||
r, err := n.Reverse(lat, lon)
|
r, err := n.Reverse(lat, lon)
|
||||||
|
|
||||||
|
@ -148,6 +154,7 @@ func (n *Nominatim) ReverseLookup(lat, lon float64) (*LookupResult, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if all fields on s is nil
|
||||||
func allFieldsNil(s interface{}) bool {
|
func allFieldsNil(s interface{}) bool {
|
||||||
v := reflect.ValueOf(s)
|
v := reflect.ValueOf(s)
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package direction
|
package direction
|
||||||
|
|
||||||
|
// Cardinal direction in unicode arrow
|
||||||
const (
|
const (
|
||||||
NORTH = "↑"
|
NORTH string = "↑"
|
||||||
SOUTH = "↓"
|
SOUTH string = "↓"
|
||||||
WEST = "←"
|
WEST string = "←"
|
||||||
EAST = "→"
|
EAST string = "→"
|
||||||
NORTH_WEST = "↖"
|
NORTH_WEST string = "↖"
|
||||||
NORTH_EAST = "↗"
|
NORTH_EAST string = "↗"
|
||||||
SOUTH_WEST = "↙"
|
SOUTH_WEST string = "↙"
|
||||||
SOUTH_EAST = "↘"
|
SOUTH_EAST string = "↘"
|
||||||
)
|
)
|
||||||
|
|
9
yr/yr.go
9
yr/yr.go
|
@ -18,6 +18,7 @@ type Client struct {
|
||||||
cache cache.Cache[ForecastResult]
|
cache cache.Cache[ForecastResult]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New default Yr client
|
||||||
func New() (*Client, error) {
|
func New() (*Client, error) {
|
||||||
siteName := "git.sr.ht/~timharek/yr"
|
siteName := "git.sr.ht/~timharek/yr"
|
||||||
met, err := met.New(siteName)
|
met, err := met.New(siteName)
|
||||||
|
@ -38,6 +39,7 @@ type wind struct {
|
||||||
Direction float64 `json:"direction"`
|
Direction float64 `json:"direction"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns wind direction to an unicode arrow
|
||||||
func (w *wind) DirectionToString() string {
|
func (w *wind) DirectionToString() string {
|
||||||
return windDirection(w.Direction)
|
return windDirection(w.Direction)
|
||||||
}
|
}
|
||||||
|
@ -68,6 +70,7 @@ func windDirection(d float64) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A forecast
|
||||||
type Forecast struct {
|
type Forecast struct {
|
||||||
nominatim.LookupResult
|
nominatim.LookupResult
|
||||||
Time time.Time `json:"time"`
|
Time time.Time `json:"time"`
|
||||||
|
@ -76,6 +79,7 @@ type Forecast struct {
|
||||||
Wind wind `json:"wind"` // In m/s
|
Wind wind `json:"wind"` // In m/s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A forecast result with metadata
|
||||||
type ForecastResult struct {
|
type ForecastResult struct {
|
||||||
Expires time.Time `json:"expires"`
|
Expires time.Time `json:"expires"`
|
||||||
LastModified time.Time `json:"lastModified"`
|
LastModified time.Time `json:"lastModified"`
|
||||||
|
@ -83,6 +87,7 @@ type ForecastResult struct {
|
||||||
Forecast []Forecast `json:"forecast"`
|
Forecast []Forecast `json:"forecast"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Current forecast for q
|
||||||
func (c *Client) Now(q string) (*ForecastResult, error) {
|
func (c *Client) Now(q string) (*ForecastResult, error) {
|
||||||
cacheResult, err := c.cache.Get(q)
|
cacheResult, err := c.cache.Get(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -103,6 +108,7 @@ func (c *Client) Now(q string) (*ForecastResult, error) {
|
||||||
}, &coords.Location)
|
}, &coords.Location)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Current forecast for coords
|
||||||
func (c *Client) NowCoords(coords *nominatim.Coordinates, location *string) (*ForecastResult, error) {
|
func (c *Client) NowCoords(coords *nominatim.Coordinates, location *string) (*ForecastResult, error) {
|
||||||
result, err := c.ForecastCoords(coords, location)
|
result, err := c.ForecastCoords(coords, location)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -114,6 +120,7 @@ func (c *Client) NowCoords(coords *nominatim.Coordinates, location *string) (*Fo
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forecast for q
|
||||||
func (c *Client) Forecast(q string) (*ForecastResult, error) {
|
func (c *Client) Forecast(q string) (*ForecastResult, error) {
|
||||||
cacheResult, err := c.cache.Get(q)
|
cacheResult, err := c.cache.Get(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -134,6 +141,7 @@ func (c *Client) Forecast(q string) (*ForecastResult, error) {
|
||||||
}, &coords.Location)
|
}, &coords.Location)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forecast for coords
|
||||||
func (c *Client) ForecastCoords(coords *nominatim.Coordinates, location *string) (*ForecastResult, error) {
|
func (c *Client) ForecastCoords(coords *nominatim.Coordinates, location *string) (*ForecastResult, error) {
|
||||||
coordCacheName := fmt.Sprintf("%.4f_%.4f", coords.Latitude, coords.Longitude)
|
coordCacheName := fmt.Sprintf("%.4f_%.4f", coords.Latitude, coords.Longitude)
|
||||||
cacheResult, err := c.cache.Get(coordCacheName)
|
cacheResult, err := c.cache.Get(coordCacheName)
|
||||||
|
@ -224,6 +232,7 @@ func (c *Client) ForecastCoords(coords *nominatim.Coordinates, location *string)
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to sort met.Timeseries
|
||||||
func sortTimeSeries(a, b met.Timeseries) int {
|
func sortTimeSeries(a, b met.Timeseries) int {
|
||||||
return cmp.Compare(a.Time.Unix(), b.Time.Unix())
|
return cmp.Compare(a.Time.Unix(), b.Time.Unix())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue