initial commit
This commit is contained in:
37
.gitignore
vendored
Normal file
37
.gitignore
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/go
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=go
|
||||||
|
|
||||||
|
### Go ###
|
||||||
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
|
#
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
||||||
|
|
||||||
|
# Go workspace file
|
||||||
|
go.work
|
||||||
|
|
||||||
|
### Go Patch ###
|
||||||
|
/vendor/
|
||||||
|
/Godeps/
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/go
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
|
=======
|
||||||
|
.env
|
||||||
|
get-weather
|
||||||
|
>>>>>>> 1f5ce74 (updated gitignore)
|
241
get-weather.go
Normal file
241
get-weather.go
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
|
||||||
|
"vikingowl/getweather/lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
var city = "<CITY>"
|
||||||
|
var apiKey = "" // get your api key on https://openweathermap.org/
|
||||||
|
var location_lat = ""
|
||||||
|
var location_lon = ""
|
||||||
|
var units = "metric"
|
||||||
|
var temperature_unit = "C"
|
||||||
|
|
||||||
|
var 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrettyPrint to print struct in a readable way
|
||||||
|
func PrettyPrint(i interface{}) string {
|
||||||
|
s, _ := json.MarshalIndent(i, "", "\t")
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setColor(apiIcon string) (string, string) {
|
||||||
|
var color string
|
||||||
|
var 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 color, icon
|
||||||
|
}
|
||||||
|
|
||||||
|
func setUrls(apiKey string) lib.Urls {
|
||||||
|
urls := lib.Urls{}
|
||||||
|
baseUrl := "https://api.openweathermap.org/data/2.5"
|
||||||
|
if city == "<CITY>" {
|
||||||
|
if location_lat == "" && location_lon == "" {
|
||||||
|
res, err := http.Get("https://location.services.mozilla.com/v1/geolocate?key=geoclue")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
location := lib.GeoLocation{}
|
||||||
|
if err := json.Unmarshal(body, &location); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
location_lat = fmt.Sprintf("%v", location.Location.Lat)
|
||||||
|
location_lon = fmt.Sprintf("%v", location.Location.Lon)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 urls
|
||||||
|
}
|
||||||
|
|
||||||
|
func getWeather(url string) (lib.Weather, error) {
|
||||||
|
weather := lib.Weather{}
|
||||||
|
|
||||||
|
res, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &weather); err != nil {
|
||||||
|
log.Fatal("weather: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return weather, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getForecast(url string) (lib.Forecast, error) {
|
||||||
|
forecast := lib.Forecast{}
|
||||||
|
|
||||||
|
res, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &forecast); err != nil {
|
||||||
|
log.Fatal("forecast: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return forecast, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := godotenv.Load(".env"); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if apiKey == "" {
|
||||||
|
apiKey = os.Getenv("API_KEY")
|
||||||
|
if apiKey == "" {
|
||||||
|
fmt.Println("You need an API KEY to use this script! Get one on https://openweathermap.org/")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if location_lat == "" {
|
||||||
|
location_lat = os.Getenv("LAT")
|
||||||
|
}
|
||||||
|
if location_lon == "" {
|
||||||
|
location_lon = os.Getenv("LNG")
|
||||||
|
}
|
||||||
|
|
||||||
|
urls := setUrls(apiKey)
|
||||||
|
weatherData, wErr := getWeather(urls.Url)
|
||||||
|
forecastData, fErr := getForecast(urls.Url_forecast)
|
||||||
|
|
||||||
|
var curr string
|
||||||
|
var forecast string
|
||||||
|
var atmosphere string
|
||||||
|
var atmosphereForecast string
|
||||||
|
|
||||||
|
// process weather data
|
||||||
|
if wErr == nil {
|
||||||
|
// 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 fErr == nil {
|
||||||
|
// 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 = "勒"
|
||||||
|
}
|
||||||
|
|
||||||
|
if atmosphere == "" {
|
||||||
|
fmt.Printf("%s %s", curr, forecast)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s %s", atmosphere, atmosphereForecast)
|
||||||
|
}
|
||||||
|
}
|
11
go.mod
Normal file
11
go.mod
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
module vikingowl/getweather
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require rsc.io/quote v1.5.2
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/joho/godotenv v1.4.0 // indirect
|
||||||
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
|
||||||
|
rsc.io/sampler v1.3.0 // indirect
|
||||||
|
)
|
8
go.sum
Normal file
8
go.sum
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||||
|
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
|
||||||
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
|
||||||
|
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
|
||||||
|
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
|
||||||
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
115
lib/interfaces.go
Normal file
115
lib/interfaces.go
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
type Urls struct {
|
||||||
|
Url string
|
||||||
|
Url_forecast string
|
||||||
|
}
|
||||||
|
|
||||||
|
type GeoLocation struct {
|
||||||
|
Accuracy float64 `json:"accuracy"`
|
||||||
|
Location struct {
|
||||||
|
Lat float64 `json:"lat"`
|
||||||
|
Lon float64 `json:"lng"`
|
||||||
|
} `json:"location"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Forecast struct {
|
||||||
|
Cod string `json:"cod"`
|
||||||
|
Message int `json:"message"`
|
||||||
|
Cnt int `json:"cnt"`
|
||||||
|
List []struct {
|
||||||
|
Dt int `json:"dt"`
|
||||||
|
Main struct {
|
||||||
|
Temp float64 `json:"temp"`
|
||||||
|
FeelsLike float64 `json:"feels_like"`
|
||||||
|
TempMin float64 `json:"temp_min"`
|
||||||
|
TempMax float64 `json:"temp_max"`
|
||||||
|
Pressure int `json:"pressure"`
|
||||||
|
SeaLevel int `json:"sea_level"`
|
||||||
|
GrndLevel int `json:"grnd_level"`
|
||||||
|
Humidity int `json:"humidity"`
|
||||||
|
TempKf float64 `json:"temp_kf"`
|
||||||
|
} `json:"main"`
|
||||||
|
Weather []struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Main string `json:"main"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
} `json:"weather"`
|
||||||
|
Clouds struct {
|
||||||
|
All int `json:"all"`
|
||||||
|
} `json:"clouds"`
|
||||||
|
Wind struct {
|
||||||
|
Speed float64 `json:"speed"`
|
||||||
|
Deg int `json:"deg"`
|
||||||
|
Gust float64 `json:"gust"`
|
||||||
|
} `json:"wind"`
|
||||||
|
Visibility int `json:"visibility"`
|
||||||
|
Pop float64 `json:"pop"`
|
||||||
|
Rain struct {
|
||||||
|
ThreeH float64 `json:"3h"`
|
||||||
|
} `json:"rain,omitempty"`
|
||||||
|
Sys struct {
|
||||||
|
Pod string `json:"pod"`
|
||||||
|
} `json:"sys"`
|
||||||
|
DtTxt string `json:"dt_txt"`
|
||||||
|
Snow struct {
|
||||||
|
ThreeH float64 `json:"3h"`
|
||||||
|
} `json:"snow,omitempty"`
|
||||||
|
} `json:"list"`
|
||||||
|
City struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Coord struct {
|
||||||
|
Lat float64 `json:"lat"`
|
||||||
|
Lon float64 `json:"lon"`
|
||||||
|
} `json:"coord"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
Population int `json:"population"`
|
||||||
|
Timezone int `json:"timezone"`
|
||||||
|
Sunrise int `json:"sunrise"`
|
||||||
|
Sunset int `json:"sunset"`
|
||||||
|
} `json:"city"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Weather struct {
|
||||||
|
Coord struct {
|
||||||
|
Lon float64 `json:"lon"`
|
||||||
|
Lat float64 `json:"lat"`
|
||||||
|
} `json:"coord"`
|
||||||
|
Weather []struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Main string `json:"main"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Icon string `json:"icon"`
|
||||||
|
} `json:"weather"`
|
||||||
|
Base string `json:"base"`
|
||||||
|
Main struct {
|
||||||
|
Temp float64 `json:"temp"`
|
||||||
|
FeelsLike float64 `json:"feels_like"`
|
||||||
|
TempMin float64 `json:"temp_min"`
|
||||||
|
TempMax float64 `json:"temp_max"`
|
||||||
|
Pressure int `json:"pressure"`
|
||||||
|
Humidity int `json:"humidity"`
|
||||||
|
} `json:"main"`
|
||||||
|
Visibility int `json:"visibility"`
|
||||||
|
Wind struct {
|
||||||
|
Speed float64 `json:"speed"`
|
||||||
|
Deg int `json:"deg"`
|
||||||
|
} `json:"wind"`
|
||||||
|
Clouds struct {
|
||||||
|
All int `json:"all"`
|
||||||
|
} `json:"clouds"`
|
||||||
|
Dt int `json:"dt"`
|
||||||
|
Sys struct {
|
||||||
|
Type int `json:"type"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
Sunrise int `json:"sunrise"`
|
||||||
|
Sunset int `json:"sunset"`
|
||||||
|
} `json:"sys"`
|
||||||
|
Timezone int `json:"timezone"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Cod int `json:"cod"`
|
||||||
|
}
|
Reference in New Issue
Block a user