From 740af88a2a75ac60f89a7d64aa9d59f8298a451c Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Mon, 8 Aug 2022 03:50:24 -0400 Subject: [PATCH] Reorgainzed menus, added search by zip and city --- cmd/advanced.go | 104 +++++++++++++++++++++++++++--------------------- cmd/history.go | 12 ------ cmd/location.go | 22 ++++++++-- cmd/main.go | 12 ++++++ cmd/menu.go | 35 +++++++++++----- cmd/weather.go | 27 +++++++++++++ 6 files changed, 142 insertions(+), 70 deletions(-) diff --git a/cmd/advanced.go b/cmd/advanced.go index 26e1e02..ada31b6 100644 --- a/cmd/advanced.go +++ b/cmd/advanced.go @@ -8,15 +8,13 @@ import ( "strings" ) +// Display advanced menu and get user input func advancedMenu(app *Application) { - var option string - // Menu loop for option != "0" { fmt.Print("\nAdvanced Menu\n-------------\n\n") - fmt.Printf("1. Change units (Default: imperial; Current: %s)\n", app.Config.Units) fmt.Println("2. Enter precise location") fmt.Println("3. Get historical data") @@ -30,49 +28,63 @@ func advancedMenu(app *Application) { } option = strings.TrimSuffix(input, "\n") - // Check user input - if option == "1" { - current := app.Config.Units - if current == "imperial" { - app.Config.Units = "metric" - } else { - app.Config.Units = "imperial" - } - fmt.Printf("\nChanged units from %s to %s...\n\n", current, app.Config.Units) - } else if option == "2" { - - // Loop to validate location entered - var validLoc bool - for !validLoc { - getPreciseLocation(app) - getCurrent(app) - - if app.Forecast.Weather.Temp != -500.00 { - validLoc = true - } else { - fmt.Println("I couldn't get any information for that location.") - fmt.Println("Are you sure the coordinates are valid?") - } - } - printWeather(app) - app.Forecast.Weather.Temp = -500.00 - - } else if option == "3" { - var validLoc bool - for !validLoc { - getPreciseLocation(app) - getDate(app) - getHistoricalData(app.Client, app) - - if app.HistoricalForecast.Temp != -500.00 { - validLoc = true - } else { - fmt.Println("I couldn't get any information for that location.") - fmt.Println("Are you sure the coordinates are valid?") - } - } - printHistorical(app) - app.Forecast.Weather.Temp = -500.00 + if option != "0" { + doAdvanced(app, option) } } } + +// Perform the users selected option from the advanced menu +func doAdvanced(app *Application, option string) { + var isValid bool + if option == "1" { + current := app.Config.Units + if current == "imperial" { + app.Config.Units = "metric" + } else { + app.Config.Units = "imperial" + } + fmt.Printf("\nChanged units from %s to %s...\n\n", current, app.Config.Units) + } else if option == "2" { + for !isValid { + getPreciseLocation(app) + getCurrent(app) + isValid = validateCurrent(app) + } + printWeather(app) + app.Forecast.Weather.Temp = -500.00 + } else if option == "3" { + for !isValid { + getPreciseLocation(app) + getDate(app) + getHistoricalData(app.Client, app) + isValid = validateHistorical(app) + } + printHistorical(app) + app.Forecast.Weather.Temp = -500.00 + } +} + +// Validates results of queries by location +func validateCurrent(app *Application) bool { + var isValid bool + if app.Forecast.Weather.Temp != -500.00 { + isValid = true + } else { + fmt.Println("I couldn't get any information for that location.") + fmt.Println("Please double check the location you entered.") + } + return isValid +} + +// Validates results of queries for historical data +func validateHistorical(app *Application) bool { + var isValid bool + if app.HistoricalForecast.Temp != -500.00 { + isValid = true + } else { + fmt.Println("I couldn't get any information for that location.") + fmt.Println("Please double check the location you entered.") + } + return isValid +} diff --git a/cmd/history.go b/cmd/history.go index 18f32aa..55b9f62 100644 --- a/cmd/history.go +++ b/cmd/history.go @@ -9,18 +9,6 @@ import ( pb "codeberg.org/andcscott/weather-cli/proto" ) -type HistoricalForecast struct { - Temp float32 `json:"temp"` - FeelsLike float32 `json:"feels_like"` - Pressure uint `json:"pressure"` - Humidity uint `json:"humidity"` - Speed float32 `json:"wind_speed"` -} - -type HistoricalData struct { - HistoricalForecast []HistoricalForecast `json:"data"` -} - // Get a date from the user and save it to the config func getDate(app *Application) { diff --git a/cmd/location.go b/cmd/location.go index e889439..663b24c 100644 --- a/cmd/location.go +++ b/cmd/location.go @@ -36,11 +36,10 @@ func getLocation(app *Application) { app.Config.Latitude, app.Config.Longitude = loc[0], loc[1] } -// Prompt user for location +// Prompt user for coordinates func getPreciseLocation(app *Application) { fmt.Print("\nEnter latitude: ") - reader := bufio.NewReader(os.Stdin) input, err := reader.ReadString('\n') if err != nil { @@ -49,10 +48,27 @@ func getPreciseLocation(app *Application) { app.Config.Latitude = strings.TrimSuffix(input, "\n") fmt.Print("\nEnter longitude: ") - input, err = reader.ReadString('\n') if err != nil { log.Println(err) } app.Config.Longitude = strings.TrimSuffix(input, "\n") } + +// Prompt user for zip code +func getZip(app *Application) { + fmt.Print("\nEnter 5-digit zip code: ") + _, err := fmt.Scanf("%s", &app.Config.Location) + if err != nil { + log.Println(err) + } +} + +// Prompt user for city +func getCity(app *Application) { + fmt.Print("\nEnter city: ") + _, err := fmt.Scanf("%s", &app.Config.Location) + if err != nil { + log.Println(err) + } +} diff --git a/cmd/main.go b/cmd/main.go index d16ce39..e4eb367 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -31,6 +31,18 @@ type Forecast struct { Wind Wind `json:"wind"` } +type HistoricalForecast struct { + Temp float32 `json:"temp"` + FeelsLike float32 `json:"feels_like"` + Pressure uint `json:"pressure"` + Humidity uint `json:"humidity"` + Speed float32 `json:"wind_speed"` +} + +type HistoricalData struct { + HistoricalForecast []HistoricalForecast `json:"data"` +} + type Date struct { Year int32 Month int32 diff --git a/cmd/menu.go b/cmd/menu.go index 357b38d..1983efa 100644 --- a/cmd/menu.go +++ b/cmd/menu.go @@ -21,12 +21,18 @@ func mainMenu(app *Application) { fmt.Println(" - Added gRPC back end for historical data") fmt.Println(" - Option to search historical data added to UI") + mainMenuLoop(app) +} + +// Display main menu and get user input +func mainMenuLoop(app *Application) { var option string - // Menu loop for option != "0" { fmt.Print("\nMain Menu\n---------\n\n") - fmt.Println("1. Today's forecast (use current location, default)") - fmt.Println("2. Advanced options (Change units, precise location, etc.)") + fmt.Println("1. Use current location (default)") + fmt.Println("2. Search by zip code") + fmt.Println("3. Search by city") + fmt.Println("4. Advanced options") fmt.Print("0. Exit\n\n") // Read user input @@ -37,18 +43,29 @@ func mainMenu(app *Application) { } option = strings.TrimSuffix(input, "\n") - // Check user input - if option == "1" || option == "" { + switch option { + case "": getLocation(app) getCurrent(app) printWeather(app) - } else if option == "2" { + case "1": + getLocation(app) + getCurrent(app) + printWeather(app) + case "2": + getZip(app) + getCurrentByLoc(app) + printWeather(app) + case "3": + getCity(app) + getCurrentByLoc(app) + printWeather(app) + case "4": advancedMenu(app) - } else if option == "0" { + case "0": return - } else { + default: fmt.Print("\nOops! An error occurred, please choose a valid option.\n\n") } } - } diff --git a/cmd/weather.go b/cmd/weather.go index 71491c7..4b72565 100644 --- a/cmd/weather.go +++ b/cmd/weather.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "io/ioutil" "log" "net/http" @@ -16,6 +17,32 @@ func getCurrent(app *Application) { key := "&appid=" + app.Config.ApiKey url := "https://pro.openweathermap.org/data/2.5/weather?" + lat + lon + units + key + res, err := http.Get(url) + if err != nil { + log.Println(err) + } + defer res.Body.Close() + fmt.Println(res.Body) + body, err := ioutil.ReadAll(res.Body) + if err != nil { + log.Println(err) + } + + err = json.Unmarshal(body, &app.Forecast) + if err != nil { + log.Println(err) + } + +} + +// Query forecast by zip code +func getCurrentByLoc(app *Application) { + + zip := app.Config.Location + units := "&units=" + app.Config.Units + key := "&appid=" + app.Config.ApiKey + url := "https://pro.openweathermap.org/data/2.5/weather?q=" + zip + units + key + res, err := http.Get(url) if err != nil { log.Println(err)