diff --git a/weather/README.md b/weather/README.md new file mode 100644 index 0000000..2330573 --- /dev/null +++ b/weather/README.md @@ -0,0 +1,5 @@ +# Weather Scripts + +### Definition + +These scripts should be used to demonstrate how get your local weather and/or weather forecasts. diff --git a/weather/get-weather.nu b/weather/get-weather.nu new file mode 100644 index 0000000..9b0565d --- /dev/null +++ b/weather/get-weather.nu @@ -0,0 +1,210 @@ +################################################### +## 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] + ["https://ipwhois.app/json/" city region country_code latitude longitude] + ] +} + +def get_my_location [index: int] { + let loc_json = (fetch (locations | nth $index).location) + let city_column = (locations | nth $index).city_column + let state_column = (locations | nth $index).state_column + let country_column = (locations | nth $index).country_column + let lat_column = (locations | nth $index).lat_column + let lon_column = (locations | nth $index).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 | into column_path)) + if ($lookup_state | str length) > 2 { + let state = (state_abbrev_lookup $lookup_state) + $"($loc_json | get ($city_column | into column_path)),($state),($loc_json | get ($country_column | into column_path))" + } { + $"($loc_json | get ($city_column | into column_path)),($loc_json | get ($state_column | into column_path)),($loc_json | get ($country_column | into column_path))" + } + } { + $"($loc_json | get ($city_column | into column_path)),($loc_json | get ($state_column | into column_path))" + } + } { + $"($loc_json | get ($city_column | into column_path))" + } + } { + "No City Found" + } +} + +let URL_QUERY_LOCATION = "https://api.openweathermap.org/geo/1.0/direct" +let TOKEN = "85a4e3c55b73909f42c6a23ec35b7147" + +def get_location_by_ip [locIdx: int] { + let location = (get_my_location $locIdx) + let url = $"($URL_QUERY_LOCATION)?q=($location)&limit=5&appid=($TOKEN)" + # echo $url + fetch $url +} + +let URL_WEATHER = "https://api.openweathermap.org/data/2.5/weather" + +def get_weather_by_ip [locIdx: int, units: string] { + # units + # f = imperial aka Fahrenheit + # c = metric aka Celcius + let coords = (get_location_by_ip $locIdx) + if ($coords | length) > 1 { + [ + [msg, labels, span]; + ["Error getting location", "There were more than one locations found", ([[start, end]; [0, 1]])] + ] | error make + } { } + + if $units == "f" { + let units = "imperial" + let url = $"($URL_WEATHER)?lat=($coords.lat)&lon=($coords.lon)&units=($units)&appid=($TOKEN)" + # echo $url (char nl) + let weather = (fetch $url) + # echo $weather | pivot | flatten | flatten + [ + ['Weather Location' Longitude Latitude Temperature 'Feels Like' Humidity Pressure Emoji]; + [$"($weather.name), ($weather.sys.country)" ($weather.coord.lon) ($weather.coord.lat) $"($weather.main.temp | into string -d 1) °F" $"($weather.main.feels_like | into string -d 1) °F" ($weather.main.humidity) ($weather.main.pressure) (get_icon_from_table $weather.weather.main.0)] + ] + } { + let units = "metric" + let url = $"($URL_WEATHER)?lat=($coords.lat)&lon=($coords.lon)&units=($units)&appid=($TOKEN)" + # echo $url (char nl) + let weather = (fetch $url) + # echo $weather | pivot | flatten | flatten + [ + ['Weather Location' Longitude Latitude Temperature 'Feels Like' Humidity Pressure Emoji]; + [$"($weather.name), ($weather.sys.country)" ($weather.coord.lon) ($weather.coord.lat) $"($weather.main.temp | into string -d 1) °C" $"($weather.main.feels_like | into string -d 1) °C" ($weather.main.humidity) ($weather.main.pressure) (get_icon_from_table $weather.weather.main.0)] + ] + } +} + +def weather_emoji_table [] { + [ + [name, icon]; + ['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 | where name == $w | get icon +} + +# Get the local weather by ip address +def get_weather [ + --locIdx(-l): int # The location id 0-3 + --units(-u): string # The units "f" or "c" + ] { + let is_loc_empty = ($locIdx | empty?) + let is_units_empty = ($units | empty?) + + let no_loc_no_unit = ($is_loc_empty == $true && $is_units_empty == $true) + let no_loc_with_unit = ($is_loc_empty == $true && $is_units_empty == $false) + let with_loc_no_unit = ($is_loc_empty == $false && $is_units_empty == $true) + let with_loc_with_unit = ($is_loc_empty == $false && $is_units_empty == $false) + + if $no_loc_no_unit { + (get_weather_by_ip 0 "f") + } { } + + if $no_loc_with_unit { + (get_weather_by_ip 0 $units) + } { } + + if $with_loc_no_unit { + (get_weather_by_ip $locIdx "f") + } { } + + if $with_loc_with_unit { + (get_weather_by_ip $locIdx $units) + } { } +} + +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 = ( + [ + [state abbrev]; + ["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 | where state == $state_name | get abbrev +} + +# 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. \ No newline at end of file