mirror of
https://github.com/glanceapp/glance.git
synced 2024-11-22 00:13:55 +01:00
Allow specifying state in weather location
This commit is contained in:
parent
ad06146784
commit
d8d6625478
@ -579,6 +579,15 @@ Example:
|
||||
location: London, United Kingdom
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> US cities which have common names can have their state specified as the second parameter like such:
|
||||
>
|
||||
> * Greenville, North Carolina, United States
|
||||
> * Greenville, South Carolina, United States
|
||||
> * Greenville, Mississippi, United States
|
||||
|
||||
|
||||
Preview:
|
||||
|
||||
![](images/weather-widget-preview.png)
|
||||
@ -592,6 +601,7 @@ Each bar represents a 2 hour interval. The yellow background represents sunrise
|
||||
| location | string | yes | |
|
||||
| units | string | no | metric |
|
||||
| hide-location | boolean | no | false |
|
||||
| show-area-name | boolean | no | false |
|
||||
|
||||
##### `location`
|
||||
The name of the city and country to fetch weather information for. Attempting to launch the applcation with an invalid location will result in an error. You can use the [gecoding API page](https://open-meteo.com/en/docs/geocoding-api) to search for your specific location. Glance will use the first result from the list if there are multiple.
|
||||
@ -602,6 +612,19 @@ Whether to show the temperature in celsius or fahrenheit, possible values are `m
|
||||
##### `hide-location`
|
||||
Optionally don't display the location name on the widget.
|
||||
|
||||
##### `show-area-name`
|
||||
Whether to display the state/administrative area in the location name. If set to `true` the location will be displayed as:
|
||||
|
||||
```
|
||||
Greenville, North Carolina, United States
|
||||
```
|
||||
|
||||
Otherwise, if set to `false` (which is the default) it'll be displayed as:
|
||||
|
||||
```
|
||||
Greenville, United States
|
||||
```
|
||||
|
||||
### Monitor
|
||||
Display a list of sites and whether they are reachable (online) or not. This is determined by sending a HEAD request to the specified URL, if the response is 200 then the site is OK. The time it took to receive a response is also shown in milliseconds.
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
{{ if not .HideLocation }}
|
||||
<div class="flex items-center justify-center margin-top-15 gap-7 size-h5">
|
||||
<div class="location-icon"></div>
|
||||
<div class="text-truncate">{{ .Place.Name }}, {{ .Place.Country }}</div>
|
||||
<div class="text-truncate">{{ .Place.Name }},{{ if .ShowAreaName }} {{ .Place.Area }},{{ end }} {{ .Place.Country }}</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "time/tzdata"
|
||||
@ -17,6 +18,7 @@ type PlacesResponseJson struct {
|
||||
|
||||
type PlaceJson struct {
|
||||
Name string
|
||||
Area string `json:"admin1"`
|
||||
Latitude float64
|
||||
Longitude float64
|
||||
Timezone string
|
||||
@ -48,8 +50,41 @@ type weatherColumn struct {
|
||||
HasPrecipitation bool
|
||||
}
|
||||
|
||||
var commonCountryAbbreviations = map[string]string{
|
||||
"US": "United States",
|
||||
"USA": "United States",
|
||||
"UK": "United Kingdom",
|
||||
}
|
||||
|
||||
func expandCountryAbbreviations(name string) string {
|
||||
if expanded, ok := commonCountryAbbreviations[strings.TrimSpace(name)]; ok {
|
||||
return expanded
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
// Separates the location that Open Meteo accepts from the administrative area
|
||||
// which can then be used to filter to the correct place after the list of places
|
||||
// has been retrieved. Also expands abbreviations since Open Meteo does not accept
|
||||
// country names like "US", "USA" and "UK"
|
||||
func parsePlaceName(name string) (string, string) {
|
||||
parts := strings.Split(name, ",")
|
||||
|
||||
if len(parts) == 1 {
|
||||
return name, ""
|
||||
}
|
||||
|
||||
if len(parts) == 2 {
|
||||
return parts[0] + ", " + expandCountryAbbreviations(parts[1]), ""
|
||||
}
|
||||
|
||||
return parts[0] + ", " + expandCountryAbbreviations(parts[2]), strings.TrimSpace(parts[1])
|
||||
}
|
||||
|
||||
func FetchPlaceFromName(location string) (*PlaceJson, error) {
|
||||
requestUrl := fmt.Sprintf("https://geocoding-api.open-meteo.com/v1/search?name=%s&count=1&language=en&format=json", url.QueryEscape(location))
|
||||
location, area := parsePlaceName(location)
|
||||
requestUrl := fmt.Sprintf("https://geocoding-api.open-meteo.com/v1/search?name=%s&count=10&language=en&format=json", url.QueryEscape(location))
|
||||
request, _ := http.NewRequest("GET", requestUrl, nil)
|
||||
responseJson, err := decodeJsonFromRequest[PlacesResponseJson](defaultClient, request)
|
||||
|
||||
@ -61,7 +96,24 @@ func FetchPlaceFromName(location string) (*PlaceJson, error) {
|
||||
return nil, fmt.Errorf("no places found for %s", location)
|
||||
}
|
||||
|
||||
place := &responseJson.Results[0]
|
||||
var place *PlaceJson
|
||||
|
||||
if area != "" {
|
||||
area = strings.ToLower(area)
|
||||
|
||||
for i := range responseJson.Results {
|
||||
if strings.ToLower(responseJson.Results[i].Area) == area {
|
||||
place = &responseJson.Results[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if place == nil {
|
||||
return nil, fmt.Errorf("no place found for %s in %s", location, area)
|
||||
}
|
||||
} else {
|
||||
place = &responseJson.Results[0]
|
||||
}
|
||||
|
||||
loc, err := time.LoadLocation(place.Timezone)
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
type Weather struct {
|
||||
widgetBase `yaml:",inline"`
|
||||
Location string `yaml:"location"`
|
||||
ShowAreaName bool `yaml:"show-area-name"`
|
||||
HideLocation bool `yaml:"hide-location"`
|
||||
Units string `yaml:"units"`
|
||||
Place *feed.PlaceJson `yaml:"-"`
|
||||
|
Loading…
Reference in New Issue
Block a user