mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-11-12 14:04:05 -08:00
feat(segment): open weather map
This commit is contained in:
parent
3f02ad4eb3
commit
4f08d660b9
42
docs/docs/segment-owm.md
Normal file
42
docs/docs/segment-owm.md
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
---
|
||||||
|
id: owm
|
||||||
|
title: Open Weather Map
|
||||||
|
sidebar_label: Open Weather Map
|
||||||
|
---
|
||||||
|
|
||||||
|
## What
|
||||||
|
|
||||||
|
Shows the current weather of a given location.
|
||||||
|
|
||||||
|
:::caution
|
||||||
|
|
||||||
|
You **must** request an API key at the [Open Weather Map](https://openweathermap.org/price) website.
|
||||||
|
The free tier for *Current weather and forecasts collection* is sufficient.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Sample Configuration
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "owm",
|
||||||
|
"style": "powerline",
|
||||||
|
"powerline_symbol": "\uE0B0",
|
||||||
|
"foreground": "#ffffff",
|
||||||
|
"background": "#FF0000",
|
||||||
|
"properties": {
|
||||||
|
"apikey": "<YOUR_API_KEY>",
|
||||||
|
"location": "AMSTERDAM,NL",
|
||||||
|
"units": "metric"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
- apikey: `string` - Your apikey from [Open Weather Map](https://openweathermap.org)
|
||||||
|
- location: `string` - The requested location.
|
||||||
|
Formatted as <City,STATE,COUNTRY_CODE>. City name, state code and country code divided by comma.
|
||||||
|
Please, refer to ISO 3166 for the state codes or country codes - defaults to `DE BILT,NL`
|
||||||
|
- units: `string` - Units of measurement.
|
||||||
|
Available values are standard (kelvin), metric (celsius), and imperial (fahrenheit) - defaults to `standard`
|
|
@ -44,6 +44,7 @@ module.exports = {
|
||||||
"nbgv",
|
"nbgv",
|
||||||
"node",
|
"node",
|
||||||
"os",
|
"os",
|
||||||
|
"owm",
|
||||||
"path",
|
"path",
|
||||||
"python",
|
"python",
|
||||||
"root",
|
"root",
|
||||||
|
|
|
@ -121,6 +121,7 @@ const (
|
||||||
Nbgv SegmentType = "nbgv"
|
Nbgv SegmentType = "nbgv"
|
||||||
// Rust writes the cargo version information if cargo.toml is present
|
// Rust writes the cargo version information if cargo.toml is present
|
||||||
Rust SegmentType = "rust"
|
Rust SegmentType = "rust"
|
||||||
|
OWM SegmentType = "owm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (segment *Segment) string() string {
|
func (segment *Segment) string() string {
|
||||||
|
@ -229,6 +230,7 @@ func (segment *Segment) background() string {
|
||||||
func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error {
|
func (segment *Segment) mapSegmentWithWriter(env environmentInfo) error {
|
||||||
segment.env = env
|
segment.env = env
|
||||||
functions := map[SegmentType]SegmentWriter{
|
functions := map[SegmentType]SegmentWriter{
|
||||||
|
OWM: &owm{},
|
||||||
Session: &session{},
|
Session: &session{},
|
||||||
Path: &path{},
|
Path: &path{},
|
||||||
Git: &git{},
|
Git: &git{},
|
||||||
|
|
88
src/segment_owd.go
Normal file
88
src/segment_owd.go
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type owm struct {
|
||||||
|
props *properties
|
||||||
|
env environmentInfo
|
||||||
|
temperature float64
|
||||||
|
weather string
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
APIKEY Property = "apikey"
|
||||||
|
LOCATION Property = "location"
|
||||||
|
UNITS Property = "units"
|
||||||
|
)
|
||||||
|
|
||||||
|
type weather struct {
|
||||||
|
ShortDescription string `json:"main"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
TypeID string `json:"icon"`
|
||||||
|
}
|
||||||
|
type temperature struct {
|
||||||
|
Value float64 `json:"temp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OWMDataResponse struct {
|
||||||
|
Data []weather `json:"weather"`
|
||||||
|
temperature `json:"main"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *owm) enabled() bool {
|
||||||
|
err := d.setStatus()
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *owm) string() string {
|
||||||
|
return fmt.Sprintf("%s (%g\ue33e)", d.weather, d.temperature)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *owm) setStatus() error {
|
||||||
|
apikey := d.props.getString(APIKEY, ".")
|
||||||
|
location := d.props.getString(LOCATION, "De Bilt,NL")
|
||||||
|
units := d.props.getString(UNITS, "standard")
|
||||||
|
|
||||||
|
url := fmt.Sprintf("http://api.openweathermap.org/data/2.5/weather?q=%s&units=%s&appid=%s", location, units, apikey)
|
||||||
|
body, err := d.env.doGet(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
q := new(OWMDataResponse)
|
||||||
|
err = json.Unmarshal(body, &q)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
d.temperature = q.temperature.Value
|
||||||
|
icon := ""
|
||||||
|
switch q.Data[0].TypeID {
|
||||||
|
case "01d":
|
||||||
|
icon = "\ufa98"
|
||||||
|
case "02d":
|
||||||
|
icon = "\ufa94"
|
||||||
|
case "03d":
|
||||||
|
icon = "\ue33d"
|
||||||
|
case "04d":
|
||||||
|
icon = "\ue312"
|
||||||
|
case "09d":
|
||||||
|
icon = "\ufa95"
|
||||||
|
case "10d":
|
||||||
|
icon = "\ue308"
|
||||||
|
case "11d":
|
||||||
|
icon = "\ue31d"
|
||||||
|
case "13d":
|
||||||
|
icon = "\ue31a"
|
||||||
|
case "50d":
|
||||||
|
icon = "\ue313"
|
||||||
|
}
|
||||||
|
d.weather = icon
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *owm) init(props *properties, env environmentInfo) {
|
||||||
|
d.props = props
|
||||||
|
d.env = env
|
||||||
|
}
|
139
src/segment_owd_test.go
Normal file
139
src/segment_owd_test.go
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOWDSegmentSingle(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Case string
|
||||||
|
JSONResponse string
|
||||||
|
ExpectedString string
|
||||||
|
ExpectedEnabled bool
|
||||||
|
Error error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Case: "Sunny Display",
|
||||||
|
JSONResponse: `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
|
||||||
|
ExpectedString: "\ufa98 (20\ue33e)",
|
||||||
|
ExpectedEnabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Error in retrieving data",
|
||||||
|
JSONResponse: "nonsense",
|
||||||
|
Error: errors.New("Something went wrong"),
|
||||||
|
ExpectedEnabled: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
env := &MockedEnvironment{}
|
||||||
|
props := &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
APIKEY: "key",
|
||||||
|
LOCATION: "AMSTERDAM,NL",
|
||||||
|
UNITS: "metric",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
url := "http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key"
|
||||||
|
|
||||||
|
env.On("doGet", url).Return([]byte(tc.JSONResponse), tc.Error)
|
||||||
|
|
||||||
|
o := &owm{
|
||||||
|
props: props,
|
||||||
|
env: env,
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled := o.enabled()
|
||||||
|
assert.Equal(t, tc.ExpectedEnabled, enabled, tc.Case)
|
||||||
|
if !enabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, tc.ExpectedString, o.string(), tc.Case)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOWDSegmentIcons(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Case string
|
||||||
|
IconID string
|
||||||
|
ExpectedIconString string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Case: "Sunny Display",
|
||||||
|
IconID: "01d",
|
||||||
|
ExpectedIconString: "\ufa98",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Light clouds Display",
|
||||||
|
IconID: "02d",
|
||||||
|
ExpectedIconString: "\ufa94",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Cloudy Display",
|
||||||
|
IconID: "03d",
|
||||||
|
ExpectedIconString: "\ue33d",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Broken Clouds Display",
|
||||||
|
IconID: "04d",
|
||||||
|
ExpectedIconString: "\ue312",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Shower Rain Display",
|
||||||
|
IconID: "09d",
|
||||||
|
ExpectedIconString: "\ufa95",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Rain Display",
|
||||||
|
IconID: "10d",
|
||||||
|
ExpectedIconString: "\ue308",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Thunderstorm Display",
|
||||||
|
IconID: "11d",
|
||||||
|
ExpectedIconString: "\ue31d",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Snow Display",
|
||||||
|
IconID: "13d",
|
||||||
|
ExpectedIconString: "\ue31a",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Case: "Fog Display",
|
||||||
|
IconID: "50d",
|
||||||
|
ExpectedIconString: "\ue313",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
env := &MockedEnvironment{}
|
||||||
|
props := &properties{
|
||||||
|
values: map[Property]interface{}{
|
||||||
|
APIKEY: "key",
|
||||||
|
LOCATION: "AMSTERDAM,NL",
|
||||||
|
UNITS: "metric",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
url := "http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key"
|
||||||
|
response := fmt.Sprintf(`{"weather":[{"icon":"%s"}],"main":{"temp":20}}`, tc.IconID)
|
||||||
|
expectedString := fmt.Sprintf("%s (20\ue33e)", tc.ExpectedIconString)
|
||||||
|
|
||||||
|
env.On("doGet", url).Return([]byte(response), nil)
|
||||||
|
|
||||||
|
o := &owm{
|
||||||
|
props: props,
|
||||||
|
env: env,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Nil(t, o.setStatus())
|
||||||
|
assert.Equal(t, expectedString, o.string(), tc.Case)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1518,6 +1518,41 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"if": {
|
||||||
|
"properties": {
|
||||||
|
"type": { "const": "owm" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"then": {
|
||||||
|
"title": "Open Weather Map Segment",
|
||||||
|
"description": "Displays the current weather from the Open Weather Map system",
|
||||||
|
"properties": {
|
||||||
|
"properties": {
|
||||||
|
"properties": {
|
||||||
|
"apikey": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "apikey",
|
||||||
|
"description": "The apikey used for the api call (Required)",
|
||||||
|
"default": "."
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "location",
|
||||||
|
"description": "Location to use for the api call. Formatted as <City>,<STATE>,<COUNTRY_CODE>. City name, state code and country code divided by comma. Please, refer to ISO 3166 for the state codes or country codes.",
|
||||||
|
"default": "De Bilt,NL"
|
||||||
|
},
|
||||||
|
"units": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "units",
|
||||||
|
"description": "Units of measurement. Available values are standard (kelvin), metric (celsius), and imperial (fahrenheit). Default is standard",
|
||||||
|
"default": "standard"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"if": {
|
"if": {
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -1652,4 +1687,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue