package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "strings" log "github.com/sirupsen/logrus" interfaces "vikingowl/poly-weather-script-go/interfaces" ) // Settings var ( // optional city = "" location_lat = "" location_lon = "" // required apiKey = "" // get your api key on https://openweathermap.org/ units = "metric" temperature_unit = "C" baseUrl = "https://api.openweathermap.org/data/2.5" atmophere_icons_list = map[int]string{ 701: "", // Mist 711: "", // Smoke 721: "", // Haze 731: "", // Dust (Sand / dust whirls) 741: "", // Fog 751: "", // Sand 761: "", // Dust 762: "", // Ash 771: "", // Squalls 781: "", // Tornado } ) func setColor(apiIcon string) (color string, icon string) { colorIcons := map[string]map[string]string{ "#fdd835": { // yellow "01d": "", "01n": "", "02d": "", "02n": "", "04d": "", "04n": "", "11d": "", "11n": "", }, "$foreground": { // foreground "03d": "", "03n": "", }, "#42a5f5": { // blue "09d": "", "09n": "", "10d": "", "10n": "", }, "#4dd0e1": { // cyan "13d": "ﰕ", "13n": "ﰕ", }, "#9e9e9e": { // gray "50d": "", "50n": "", }, } for colorI, icons := range colorIcons { if iconI, f := icons[apiIcon]; f { color = colorI icon = iconI } } return } func getLocation() { res, err := http.Get("https://location.services.mozilla.com/v1/geolocate?key=geoclue") if err != nil { log.Warningf("[GL] unable to get location: %v", err) } if res.StatusCode >= 200 && res.StatusCode < 300 { defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { log.Warningf("[GL] unable to read location response: %v", err) } location := interfaces.GeoLocation{} if err := json.Unmarshal(body, &location); err != nil { log.Warningf("[GL] unable to marshal location data: %v", err) } location_lat = fmt.Sprint(location.Location.Lat) location_lon = fmt.Sprint(location.Location.Lon) } else { // TODO: needs updating if errors occur log.Warningf("[GL] something went wrong while getting the location: %v", res.StatusCode) } } func setUrls(apiKey string) (urls interfaces.Urls) { if city == "" { if location_lat == "" && location_lon == "" { getLocation() } urls.Url = fmt.Sprintf("%s/weather?lat=%s&lon=%s&units=%s&appid=%s", baseUrl, location_lat, location_lon, units, apiKey) urls.Url_forecast = fmt.Sprintf("%s/forecast?lat=%s&lon=%s&units=%s&appid=%s", baseUrl, location_lat, location_lon, units, apiKey) } else { urls.Url = fmt.Sprintf("%s/weather?q=%s&units=%s&appid=%s", baseUrl, city, units, apiKey) urls.Url_forecast = fmt.Sprintf("%s/forecast?q=%s&units=%s&appid=%s", baseUrl, city, units, apiKey) } return } func getWeather(url string) (weather interfaces.Weather) { res, err := http.Get(url) if err != nil { log.Warningf("[GW] unable to get weather: %v", err) } if res.StatusCode >= 200 && res.StatusCode < 300 { defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { log.Warningf("[GW] unable to read weather: %v", err) } if err := json.Unmarshal(body, &weather); err != nil { log.Warningf("[GW] unable to marshal weather data: %v", err) } } else { if res.StatusCode == 400 { log.Warning("[GW] bad request") } else if res.StatusCode == 401 { log.Warning("[GW] unauthorized - wrong api key") } else { log.Warningf("[GW] something went wrong while getting the weather: %v", res.StatusCode) } } return } func getForecast(url string) (forecast interfaces.Forecast) { res, err := http.Get(url) if err != nil { log.Warningf("[GF] unable to get forecast: %v", err) } if res.StatusCode >= 200 && res.StatusCode < 300 { defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) if err != nil { log.Warningf("[GF] unable to read forecast: %v", err) } if err := json.Unmarshal(body, &forecast); err != nil { log.Warningf("[GF] unable to marshal forecast data: %v", err) } } else { if res.StatusCode == 400 { log.Warning("[GF] bad request") } else if res.StatusCode == 401 { log.Warning("[GF] unauthorized - wrong api key") } else { log.Warningf("[GF] something went wrong while getting the forecast: %v", res.StatusCode) } } return } func main() { // try to get apiKey and location from environment // LOOKS LIKE THIS DOESN'T WORK IN POLYBAR // TODO: Needs fix // if apiKey == "" { // apiKey = os.Getenv("OPEN_WEATHER_MAP_API_KEY") // if apiKey == "" { // log.Warning("[main] you need an API KEY to use this script! Get one on https://openweathermap.org/") // os.Exit(1) // } // } // if location_lat == "" { // location_lat = fmt.Sprint(os.Getenv("LAT")) // } // if location_lon == "" { // location_lon = fmt.Sprint(os.Getenv("LNG")) // } // ----------------------------------------------- // api calls urls := setUrls(apiKey) weatherData := getWeather(urls.Url) forecastData := getForecast(urls.Url_forecast) var ( curr string forecast string atmosphere string atmosphereForecast string ) // process weather data if weatherData.Weather[0].ID != 0 { // Get info from data id := int(weatherData.Weather[0].ID) group := strings.Title(weatherData.Weather[0].Main) apiIcon := weatherData.Weather[0].Icon temp := fmt.Sprintf("%.1f", weatherData.Main.Temp) color, icon := setColor(apiIcon) // Load other icons for Atmosphere group if group == "Atmosphere" { atmosphere = "%{F#e57c46}" + atmophere_icons_list[id] + "%{F$foreground} " + temp + "°" + temperature_unit + "%{F-}" } curr = "%{F" + color + "}" + icon + "%{F$foreground} " + temp + "°" + temperature_unit + "%{F-}" } else { forecast = "勒" } // process forecast data if forecastData.List[0].Weather[0].ID != 0 { // Get info from data id := int(forecastData.List[0].Weather[0].ID) group := strings.Title(forecastData.List[0].Weather[0].Main) apiIcon := forecastData.List[0].Weather[0].Icon temp := fmt.Sprintf("%.1f", forecastData.List[0].Main.Temp) color, icon := setColor(apiIcon) // Load other icons for Atmosphere group if group == "Atmosphere" { atmosphereForecast = "%{F#e57c46}" + atmophere_icons_list[id] + "{F$foreground} " + temp + "°" + temperature_unit + "%{F-}" } forecast = "%{F" + color + "}" + icon + "%{F$foreground} " + temp + "°" + temperature_unit + "%{F-}" } else { forecast = "勒" } // print output if atmosphere == "" { fmt.Printf("%s  %s", curr, forecast) } else { fmt.Printf("%s  %s", atmosphere, atmosphereForecast) } }