mirror of
https://codeberg.org/hyperreal/nushell-config
synced 2024-11-25 12:23:42 +01:00
316 lines
14 KiB
Plaintext
316 lines
14 KiB
Plaintext
# From https://github.com/nushell/nu_scripts/blob/main/modules/weather/get-weather.nu
|
|
|
|
###################################################
|
|
## Weather Script based on IP Address v1.0
|
|
###################################################
|
|
def locations [] {
|
|
[
|
|
[location city_column state_column country_column lat_column lon_column];
|
|
["http://ip-api.com/json/" city region countryCode lat lon]
|
|
["https://ipapi.co/json/" city region_code country_code latitude longitude]
|
|
# ["https://freegeoip.app/json/" city region_code country_code latitude longitude] # doesn't appear to be free any longer
|
|
["https://ipwhois.app/json/" city region country_code latitude longitude]
|
|
]
|
|
}
|
|
|
|
def get_my_location [index: int] {
|
|
let loc_json = (http get (locations | select $index).0.location)
|
|
let city_column = (locations | select $index).0.city_column
|
|
let state_column = (locations | select $index).0.state_column
|
|
let country_column = (locations | select $index).0.country_column
|
|
let lat_column = (locations | select $index).0.lat_column
|
|
let lon_column = (locations | select $index).0.lon_column
|
|
|
|
# echo $loc_json
|
|
if ($city_column | str length) > 1 {
|
|
if ($state_column | str length) > 1 {
|
|
if ($country_column | str length) > 1 {
|
|
let lookup_state = ($loc_json | get ($state_column))
|
|
if ($lookup_state | str length) > 2 {
|
|
let state = (state_abbrev_lookup $lookup_state)
|
|
$"($loc_json | get ($city_column)),($state),($loc_json | get ($country_column))"
|
|
} else {
|
|
$"($loc_json | get ($city_column)),($loc_json | get ($state_column)),($loc_json | get ($country_column))"
|
|
}
|
|
} else {
|
|
$"($loc_json | get ($city_column)),($loc_json | get ($state_column))"
|
|
}
|
|
} else {
|
|
$"($loc_json | get ($city_column))"
|
|
}
|
|
} else {
|
|
"No City Found"
|
|
}
|
|
}
|
|
|
|
def get_location_by_ip [locIdx: int, token: string] {
|
|
let URL_QUERY_LOCATION = "https://api.openweathermap.org/geo/1.0/direct"
|
|
let location = (get_my_location $locIdx)
|
|
let url = $"($URL_QUERY_LOCATION)?q=($location)&limit=5&appid=($token)"
|
|
http get $url
|
|
}
|
|
|
|
def show-error [msg label err] {
|
|
let span = (metadata $err).span;
|
|
error make {msg: $msg, label: {text: $label, span: $span } }
|
|
}
|
|
|
|
def get_weather_by_ip [locIdx: int, units: string, token: string] {
|
|
# units
|
|
# f = imperial aka Fahrenheit
|
|
# c = metric aka Celcius
|
|
let URL_WEATHER = "https://api.openweathermap.org/data/2.5/weather"
|
|
let URL_FORECAST = "http://api.openweathermap.org/data/2.5/forecast/daily"
|
|
let coords = (get_location_by_ip $locIdx $token)
|
|
if ($coords | length) > 1 {
|
|
show-error "Error getting location" "There were more than one locations found" $coords
|
|
}
|
|
|
|
if $units == "f" {
|
|
let units = "imperial"
|
|
let url = $"($URL_WEATHER)?lat=($coords.lat.0)&lon=($coords.lon.0)&units=($units)&appid=($token)"
|
|
let url_forecast = $"($URL_FORECAST)?lat=($coords.lat.0)&lon=($coords.lon.0)&units=($units)&appid=($token)"
|
|
let weather = (http get $url)
|
|
let forecast_data = (http get $url_forecast)
|
|
let forecast = ($forecast_data.list | each {|day|
|
|
{
|
|
id: ($day.weather.0.id)
|
|
dt: ($day.dt * 1_000_000_000 | into string | into datetime -z local | format date '%a, %b %e') #'%Y-%m-%d')
|
|
high: ($day.temp.max)
|
|
low: ($day.temp.min)
|
|
}
|
|
})
|
|
let day1 = $"($forecast | get 0.dt) (get_emoji_by_id ($forecast | get 0.id | into string)) high: ($forecast | get 0.high | into string -d 1) low: ($forecast | get 0.low | into string -d 1)"
|
|
let day2 = $"($forecast | get 1.dt) (get_emoji_by_id ($forecast | get 1.id | into string)) high: ($forecast | get 1.high | into string -d 1) low: ($forecast | get 1.low | into string -d 1)"
|
|
let day3 = $"($forecast | get 2.dt) (get_emoji_by_id ($forecast | get 2.id | into string)) high: ($forecast | get 2.high | into string -d 1) low: ($forecast | get 2.low | into string -d 1)"
|
|
let day4 = $"($forecast | get 3.dt) (get_emoji_by_id ($forecast | get 3.id | into string)) high: ($forecast | get 3.high | into string -d 1) low: ($forecast | get 3.low | into string -d 1)"
|
|
let day5 = $"($forecast | get 4.dt) (get_emoji_by_id ($forecast | get 4.id | into string)) high: ($forecast | get 4.high | into string -d 1) low: ($forecast | get 4.low | into string -d 1)"
|
|
let day6 = $"($forecast | get 5.dt) (get_emoji_by_id ($forecast | get 5.id | into string)) high: ($forecast | get 5.high | into string -d 1) low: ($forecast | get 5.low | into string -d 1)"
|
|
let day7 = $"($forecast | get 6.dt) (get_emoji_by_id ($forecast | get 6.id | into string)) high: ($forecast | get 6.high | into string -d 1) low: ($forecast | get 6.low | into string -d 1)"
|
|
{
|
|
'Weather Location': $"($weather.name), ($weather.sys.country)"
|
|
Longitude: $weather.coord.lon
|
|
Latitude: $weather.coord.lat
|
|
Temperature: $"($weather.main.temp | into string -d 1) °F"
|
|
'Feels Like': $"($weather.main.feels_like | into string -d 1) °F"
|
|
Humidity: $weather.main.humidity
|
|
Pressure: $weather.main.pressure
|
|
Emoji: (get_icon_from_table $weather.weather.main.0)
|
|
'Forecast Day 1': $day1
|
|
'Forecast Day 2': $day2
|
|
'Forecast Day 3': $day3
|
|
'Forecast Day 4': $day4
|
|
'Forecast Day 5': $day5
|
|
'Forecast Day 6': $day6
|
|
'Forecast Day 7': $day7
|
|
}
|
|
} else {
|
|
let units = "metric"
|
|
let url = $"($URL_WEATHER)?lat=($coords.lat.0)&lon=($coords.lon.0)&units=($units)&appid=($token)"
|
|
let url_forecast = $"($URL_FORECAST)?lat=($coords.lat.0)&lon=($coords.lon.0)&units=($units)&appid=($token)"
|
|
let weather = (http get $url)
|
|
let forecast_data = (http get $url_forecast)
|
|
let forecast = ($forecast_data.list | each {|day|
|
|
{
|
|
id: ($day.weather.0.id)
|
|
dt: ($day.dt * 1_000_000_000 | into string | into datetime -z local | format date '%a, %b %e') #'%Y-%m-%d')
|
|
high: ($day.temp.max)
|
|
low: ($day.temp.min)
|
|
}
|
|
})
|
|
let day1 = $"($forecast | get 0.dt) (get_emoji_by_id ($forecast | get 0.id | into string)) high: ($forecast | get 0.high | into string -d 1) low: ($forecast | get 0.low | into string -d 1)"
|
|
let day2 = $"($forecast | get 1.dt) (get_emoji_by_id ($forecast | get 1.id | into string)) high: ($forecast | get 1.high | into string -d 1) low: ($forecast | get 1.low | into string -d 1)"
|
|
let day3 = $"($forecast | get 2.dt) (get_emoji_by_id ($forecast | get 2.id | into string)) high: ($forecast | get 2.high | into string -d 1) low: ($forecast | get 2.low | into string -d 1)"
|
|
let day4 = $"($forecast | get 3.dt) (get_emoji_by_id ($forecast | get 3.id | into string)) high: ($forecast | get 3.high | into string -d 1) low: ($forecast | get 3.low | into string -d 1)"
|
|
let day5 = $"($forecast | get 4.dt) (get_emoji_by_id ($forecast | get 4.id | into string)) high: ($forecast | get 4.high | into string -d 1) low: ($forecast | get 4.low | into string -d 1)"
|
|
let day6 = $"($forecast | get 5.dt) (get_emoji_by_id ($forecast | get 5.id | into string)) high: ($forecast | get 5.high | into string -d 1) low: ($forecast | get 5.low | into string -d 1)"
|
|
let day7 = $"($forecast | get 6.dt) (get_emoji_by_id ($forecast | get 6.id | into string)) high: ($forecast | get 6.high | into string -d 1) low: ($forecast | get 6.low | into string -d 1)"
|
|
{
|
|
'Weather Location': $"($weather.name), ($weather.sys.country)"
|
|
Longitude: $weather.coord.lon
|
|
Latitude: $weather.coord.lat
|
|
Temperature: $"($weather.main.temp | into string -d 1) °C"
|
|
'Feels Like': $"($weather.main.feels_like | into string -d 1) °C"
|
|
Humidity: $weather.main.humidity
|
|
Pressure: $weather.main.pressure
|
|
Emoji: (get_icon_from_table $weather.weather.main.0)
|
|
'Forecast Day 1': $day1
|
|
'Forecast Day 2': $day2
|
|
'Forecast Day 3': $day3
|
|
'Forecast Day 4': $day4
|
|
'Forecast Day 5': $day5
|
|
'Forecast Day 6': $day6
|
|
'Forecast Day 7': $day7
|
|
}
|
|
}
|
|
}
|
|
|
|
def weather_emoji_table [] {
|
|
{
|
|
Clear: (char sun)
|
|
Clouds: (char clouds)
|
|
Rain: (char rain)
|
|
Fog: (char fog)
|
|
Mist: (char mist)
|
|
Haze: (char haze)
|
|
Snow: (char snow)
|
|
Thunderstorm: (char thunderstorm)
|
|
}
|
|
}
|
|
|
|
def get_icon_from_table [w] {
|
|
weather_emoji_table | get $w
|
|
}
|
|
|
|
# Get the local weather by ip address
|
|
export def get_weather [
|
|
--locIdx(-l): int # The location id 0-2
|
|
--units(-u): string # The units "f" or "c"
|
|
] {
|
|
let token = "85a4e3c55b73909f42c6a23ec35b7147"
|
|
|
|
let is_loc_empty = ($locIdx == null)
|
|
let is_units_empty = ($units == null)
|
|
|
|
let no_loc_no_unit = ($is_loc_empty == true and $is_units_empty == true)
|
|
let no_loc_with_unit = ($is_loc_empty == true and $is_units_empty == false)
|
|
let with_loc_no_unit = ($is_loc_empty == false and $is_units_empty == true)
|
|
let with_loc_with_unit = ($is_loc_empty == false and $is_units_empty == false)
|
|
|
|
# This is a cautionary tale, the commented out code below is returning
|
|
# and autoview is viewing the data, so no structured data is being returned.
|
|
# The ramification to this is you can't do get_weather | select Temperature Emoji
|
|
# like you should be able to. The following uncommented section below fixes it.
|
|
|
|
# Hopefully we'll be able to fix this somehow because it's easy to fall into
|
|
# this hole without knowing.
|
|
|
|
# if $no_loc_no_unit {
|
|
# echo "no_loc_no_unit"
|
|
# (get_weather_by_ip 0 "f")
|
|
# } { }
|
|
|
|
# if $no_loc_with_unit {
|
|
# echo "no_loc_with_unit"
|
|
# (get_weather_by_ip 0 $units)
|
|
# } { }
|
|
|
|
# if $with_loc_no_unit {
|
|
# echo "with_loc_no_unit"
|
|
# (get_weather_by_ip $locIdx "f")
|
|
# } { }
|
|
|
|
# if $with_loc_with_unit {
|
|
# echo "with_loc_with_unit"
|
|
# (get_weather_by_ip $locIdx $units)
|
|
# } { }
|
|
|
|
if $no_loc_no_unit {
|
|
(get_weather_by_ip 0 "f" $token)
|
|
} else if $no_loc_with_unit {
|
|
(get_weather_by_ip 0 $units $token)
|
|
} else if $with_loc_no_unit {
|
|
(get_weather_by_ip $locIdx "f" $token)
|
|
} else if $with_loc_with_unit {
|
|
(get_weather_by_ip $locIdx $units $token)
|
|
}
|
|
}
|
|
|
|
def state_abbrev_lookup [state_name: string] {
|
|
# Weather Location 3 does not return state name abbreviations
|
|
# so we have to convert a state full name to a state abbreviation
|
|
let lookup_table = {
|
|
Alabama: AL
|
|
Alaska: AK
|
|
Arizona: AZ
|
|
Arkansas: AR
|
|
California: CA
|
|
Colorado: CO
|
|
Connecticut: CT
|
|
Delaware: DE
|
|
Florida: FL
|
|
Georgia: GA
|
|
Hawaii: HI
|
|
Idaho: ID
|
|
Illinois: IL
|
|
Indiana: IN
|
|
Iowa: IA
|
|
Kansas: KS
|
|
Kentucky: KY
|
|
Louisiana: LA
|
|
Maine: ME
|
|
Maryland: MD
|
|
Massachusetts: MA
|
|
Michigan: MI
|
|
Minnesota: MN
|
|
Mississippi: MS
|
|
Missouri: MO
|
|
Montana: MT
|
|
Nebraska: NE
|
|
Nevada: NV
|
|
'New Hampshire': NH
|
|
'New Jersey': NJ
|
|
'New Mexico': NM
|
|
'New York': NY
|
|
'North Carolina': NC
|
|
'North Dakota': ND
|
|
Ohio: OH
|
|
Oklahoma: OK
|
|
Oregon: OR
|
|
Pennsylvania: PA
|
|
'Rhode Island': RI
|
|
'South Carolina': SC
|
|
'South Dakota': SD
|
|
Tennessee: TN
|
|
Texas: TX
|
|
Utah: UT
|
|
Vermont: VT
|
|
Virginia: VA
|
|
Washington: WA
|
|
'West Virginia': WV
|
|
Wisconsin: WI
|
|
Wyoming: WY
|
|
}
|
|
|
|
$lookup_table | get $state_name
|
|
}
|
|
|
|
def get_emoji_by_id [id] {
|
|
let emoji_dict = ({
|
|
"200": "⚡", "201": "⚡", "202": "⚡", "210": "⚡", "211": "⚡", "212": "⚡", "221": "⚡", "230": "⚡",
|
|
"231": "⚡", "232": "⚡",
|
|
"300": "☔", "301": "☔", "302": "☔", "310": "☔", "311": "☔",
|
|
"312": "☔", "313": "☔", "314": "☔", "321": "☔",
|
|
"500": "☔", "501": "☔", "502": "☔", "503": "☔", "504": "☔",
|
|
"511": "☔", "520": "☔", "521": "☔", "522": "☔", "531": "☔",
|
|
"600": "❄️", "601": "❄️", "602": "❄️", "611": "❄️", "612": "❄️",
|
|
"613": "❄️", "615": "❄️", "616": "❄️", "620": "❄️", "621": "❄️",
|
|
"622": "❄️",
|
|
"701": "🌫️", "711": "🌫️", "721": "🌫️", "731": "🌫️", "741": "🌫️", "751": "🌫️", "761": "🌫️", "762": "🌫️",
|
|
"771": "🌫️",
|
|
"781": "🌀",
|
|
"800": "☀️",
|
|
"801": "🌤️", "802": "🌤️", "803": "☁️", "804": "☁️",
|
|
})
|
|
|
|
($emoji_dict | get $id)
|
|
}
|
|
|
|
# To run this call
|
|
# > get_weather
|
|
# it will default to location 0 and Fahrenheit degrees
|
|
# > get_weather -l 1
|
|
# This changes to location 1. Locations are listed in the locations custom command above
|
|
# > get_weather -l 2 -u c
|
|
# This uses location 2 and Celcius degrees. f = Fahrenheit, c = Celcius
|
|
|
|
# Since I live in the USA I have not tested outside the country.
|
|
# We'll take PRs for things that are broke or augmentations.
|
|
|
|
# HOW TO USE
|
|
# put this in your config.nu file
|
|
# use /path/to/get-weather.nu get_weather
|
|
#
|
|
# then from the nushell commmand prompt type
|
|
# get_weather
|