diff --git a/docs/docs/segment-owm.md b/docs/docs/segment-owm.md index a85ba2c4..39d68092 100644 --- a/docs/docs/segment-owm.md +++ b/docs/docs/segment-owm.md @@ -27,7 +27,9 @@ The free tier for *Current weather and forecasts collection* is sufficient. "properties": { "apikey": "", "location": "AMSTERDAM,NL", - "units": "metric" + "units": "metric", + "enable_hyperlink" : false, + "http_timeout": 20 } } ``` @@ -39,4 +41,6 @@ The free tier for *Current weather and forecasts collection* is sufficient. Formatted as . 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. +- enable_hyperlink: `bool` - Displays an hyperlink to get openweathermap data +- http_timeout: `int` - The default timeout for http request is 20ms. Available values are standard (kelvin), metric (celsius), and imperial (fahrenheit) - defaults to `standard` diff --git a/src/ansi.go b/src/ansi.go index 065d5a73..c8861ea4 100644 --- a/src/ansi.go +++ b/src/ansi.go @@ -121,8 +121,8 @@ func (a *ansiUtils) lenWithoutANSI(text string) int { if len(text) == 0 { return 0 } - // replace hyperlinks - matches := findAllNamedRegexMatch(`(?P\x1b]8;;file:\/\/(.+)\x1b\\(?P.+)\x1b]8;;\x1b\\)`, text) + // replace hyperlinks(file/http/https) + matches := findAllNamedRegexMatch(`(?P\x1b]8;;(file|http|https):\/\/(.+?)\x1b\\(?P.+?)\x1b]8;;\x1b\\)`, text) for _, match := range matches { text = strings.ReplaceAll(text, match[str], match[url]) } diff --git a/src/config.go b/src/config.go index abf7427e..6088e6ba 100644 --- a/src/config.go +++ b/src/config.go @@ -40,6 +40,10 @@ type TransientPrompt struct { const ( // EnableHyperlink enable hyperlink EnableHyperlink Property = "enable_hyperlink" + // HTTPTimeout timeout used when executing http request + HTTPTimeout Property = "http_timeout" + // DefaultHTTPTimeout default timeout used when executing http request + DefaultHTTPTimeout = 20 ) func printConfigError(err error) { diff --git a/src/environment.go b/src/environment.go index ea191ab2..1f51c3fa 100644 --- a/src/environment.go +++ b/src/environment.go @@ -72,7 +72,7 @@ type environmentInfo interface { getBatteryInfo() ([]*battery.Battery, error) getShellName() string getWindowTitle(imageName, windowTitleRegex string) (string, error) - doGet(url string) ([]byte, error) + doGet(url string, timeout int) ([]byte, error) hasParentFilePath(path string) (fileInfo *fileInfo, err error) isWsl() bool stackCount() int @@ -389,9 +389,9 @@ func (env *environment) getShellName() string { return *env.args.Shell } -func (env *environment) doGet(url string) ([]byte, error) { +func (env *environment) doGet(url string, timeout int) ([]byte, error) { defer env.tracer.trace(time.Now(), "doGet", url) - ctx, cncl := context.WithTimeout(context.Background(), time.Millisecond*20) + ctx, cncl := context.WithTimeout(context.Background(), time.Millisecond*time.Duration(timeout)) defer cncl() request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { diff --git a/src/segment.go b/src/segment.go index 35b30800..985b7333 100644 --- a/src/segment.go +++ b/src/segment.go @@ -121,7 +121,8 @@ const ( Nbgv SegmentType = "nbgv" // Rust writes the cargo version information if cargo.toml is present Rust SegmentType = "rust" - OWM SegmentType = "owm" + // OWM writes the weather coming from openweatherdata + OWM SegmentType = "owm" ) func (segment *Segment) string() string { diff --git a/src/segment_owd.go b/src/segment_owm.go similarity index 68% rename from src/segment_owd.go rename to src/segment_owm.go index 6a7ed280..08aff3e3 100644 --- a/src/segment_owd.go +++ b/src/segment_owm.go @@ -10,12 +10,17 @@ type owm struct { env environmentInfo temperature float64 weather string + url string + units string } const ( - APIKEY Property = "apikey" + // APIKEY openweathermap api key + APIKEY Property = "apikey" + // LOCATION openweathermap location LOCATION Property = "location" - UNITS Property = "units" + // UNITS openweathermap units + UNITS Property = "units" ) type weather struct { @@ -38,16 +43,32 @@ func (d *owm) enabled() bool { } func (d *owm) string() string { - return fmt.Sprintf("%s (%g\ue33e)", d.weather, d.temperature) + unitIcon := "\ue33e" + switch d.units { + case "imperial": + unitIcon = "°F" // \ue341" + case "metric": + unitIcon = "°C" // \ue339" + case "": + fallthrough + case "standard": + unitIcon = "°K" // \ufa05" + } + text := fmt.Sprintf("%s (%g%s)", d.weather, d.temperature, unitIcon) + if d.props.getBool(EnableHyperlink, false) { + text = fmt.Sprintf("[%s](%s)", text, d.url) + } + return text } func (d *owm) setStatus() error { apikey := d.props.getString(APIKEY, ".") location := d.props.getString(LOCATION, "De Bilt,NL") units := d.props.getString(UNITS, "standard") + timeout := d.props.getInt(HTTPTimeout, DefaultHTTPTimeout) 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) + body, err := d.env.doGet(url, timeout) if err != nil { return err } @@ -79,6 +100,8 @@ func (d *owm) setStatus() error { icon = "\ue313" } d.weather = icon + d.url = url + d.units = units return nil } diff --git a/src/segment_owd_test.go b/src/segment_owm_test.go similarity index 93% rename from src/segment_owd_test.go rename to src/segment_owm_test.go index 11adc992..ffc4f838 100644 --- a/src/segment_owd_test.go +++ b/src/segment_owm_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestOWDSegmentSingle(t *testing.T) { +func TestOWMSegmentSingle(t *testing.T) { cases := []struct { Case string JSONResponse string @@ -19,7 +19,7 @@ func TestOWDSegmentSingle(t *testing.T) { { Case: "Sunny Display", JSONResponse: `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`, - ExpectedString: "\ufa98 (20\ue33e)", + ExpectedString: "\ufa98 (20°C)", ExpectedEnabled: true, }, { @@ -59,7 +59,7 @@ func TestOWDSegmentSingle(t *testing.T) { } } -func TestOWDSegmentIcons(t *testing.T) { +func TestOWMSegmentIcons(t *testing.T) { cases := []struct { Case string IconID string @@ -124,7 +124,7 @@ func TestOWDSegmentIcons(t *testing.T) { 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) + expectedString := fmt.Sprintf("%s (20°C)", tc.ExpectedIconString) env.On("doGet", url).Return([]byte(response), nil) diff --git a/src/segment_path_test.go b/src/segment_path_test.go index c124c40b..56a941c3 100644 --- a/src/segment_path_test.go +++ b/src/segment_path_test.go @@ -124,7 +124,7 @@ func (env *MockedEnvironment) getWindowTitle(imageName, windowTitleRegex string) return args.String(0), args.Error(1) } -func (env *MockedEnvironment) doGet(url string) ([]byte, error) { +func (env *MockedEnvironment) doGet(url string, timeout int) ([]byte, error) { args := env.Called(url) return args.Get(0).([]byte), args.Error(1) } diff --git a/src/segment_ytm.go b/src/segment_ytm.go index 6912ec94..080fe0f8 100644 --- a/src/segment_ytm.go +++ b/src/segment_ytm.go @@ -85,7 +85,8 @@ type track struct { func (y *ytm) setStatus() error { // https://github.com/ytmdesktop/ytmdesktop/wiki/Remote-Control-API url := y.props.getString(APIURL, "http://127.0.0.1:9863") - body, err := y.env.doGet(url + "/query") + httpTimeout := y.props.getInt(APIURL, DefaultHTTPTimeout) + body, err := y.env.doGet(url+"/query", httpTimeout) if err != nil { return err } diff --git a/themes/schema.json b/themes/schema.json index 04dedf46..aecef061 100644 --- a/themes/schema.json +++ b/themes/schema.json @@ -27,6 +27,18 @@ "description": "Show or hide the version number", "default": true }, + "enable_hyperlink": { + "type": "boolean", + "title": "Enable hyperlink", + "description": "Displays an hyperlink for the current segment", + "default": false + }, + "http_timeout": { + "type": "integer", + "title": "Http requst timeout", + "description": "Timeout value to use for http request", + "default": 20 + }, "display_mode": { "type": "string", "title": "Display Mode", @@ -155,7 +167,8 @@ "azfunc", "crystal", "dart", - "rust" + "rust", + "owm" ] }, "style": { @@ -681,10 +694,10 @@ "behind_color": { "$ref": "#/definitions/color" }, "ahead_color": { "$ref": "#/definitions/color" }, "branch_max_length": { - "type": "integer", - "title": "Branch max length", - "description": "the max length for the displayed branch name where 0 implies full length", - "default": 0 + "type": "integer", + "title": "Branch max length", + "description": "the max length for the displayed branch name where 0 implies full length", + "default": 0 } } } @@ -1227,17 +1240,14 @@ "description": "Replace known locations in the path with the replacements before applying the style.", "default": true }, - "enable_hyperlink": { - "type": "boolean", - "title": "Enable hyperlink", - "description": "Displays an hyperlink for the current path", - "default": false - }, "stack_count_enabled": { "type": "boolean", "title": "Show/hide stack count", "description": "Displays the stack count when using pushd/popd", "default": false + }, + "enable_hyperlink": { + "$ref": "#/definitions/enable_hyperlink" } } } @@ -1512,6 +1522,9 @@ "title": "API URL", "description": "The YTMDA Remote Control API URL", "default": "http://127.0.0.1:9863" + }, + "http_timeout": { + "$ref": "#/definitions/http_timeout" } } } @@ -1547,6 +1560,12 @@ "title": "units", "description": "Units of measurement. Available values are standard (kelvin), metric (celsius), and imperial (fahrenheit). Default is standard", "default": "standard" + }, + "enable_hyperlink": { + "$ref": "#/definitions/enable_hyperlink" + }, + "http_timeout": { + "$ref": "#/definitions/http_timeout" } } } @@ -1687,4 +1706,4 @@ } } } -} \ No newline at end of file +}