Reorgainzed menus, added search by zip and city

This commit is contained in:
Andrew Scott 2022-08-08 03:50:24 -04:00
parent 0143e501db
commit 740af88a2a
Signed by: a
GPG key ID: 3EB62D0BBB8DB381
6 changed files with 142 additions and 70 deletions

View file

@ -8,15 +8,13 @@ import (
"strings" "strings"
) )
// Display advanced menu and get user input
func advancedMenu(app *Application) { func advancedMenu(app *Application) {
var option string var option string
// Menu loop // Menu loop
for option != "0" { for option != "0" {
fmt.Print("\nAdvanced Menu\n-------------\n\n") fmt.Print("\nAdvanced Menu\n-------------\n\n")
fmt.Printf("1. Change units (Default: imperial; Current: %s)\n", app.Config.Units) fmt.Printf("1. Change units (Default: imperial; Current: %s)\n", app.Config.Units)
fmt.Println("2. Enter precise location") fmt.Println("2. Enter precise location")
fmt.Println("3. Get historical data") fmt.Println("3. Get historical data")
@ -30,49 +28,63 @@ func advancedMenu(app *Application) {
} }
option = strings.TrimSuffix(input, "\n") option = strings.TrimSuffix(input, "\n")
// Check user input if option != "0" {
if option == "1" { doAdvanced(app, option)
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
} }
} }
} }
// 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
}

View file

@ -9,18 +9,6 @@ import (
pb "codeberg.org/andcscott/weather-cli/proto" 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 // Get a date from the user and save it to the config
func getDate(app *Application) { func getDate(app *Application) {

View file

@ -36,11 +36,10 @@ func getLocation(app *Application) {
app.Config.Latitude, app.Config.Longitude = loc[0], loc[1] app.Config.Latitude, app.Config.Longitude = loc[0], loc[1]
} }
// Prompt user for location // Prompt user for coordinates
func getPreciseLocation(app *Application) { func getPreciseLocation(app *Application) {
fmt.Print("\nEnter latitude: ") fmt.Print("\nEnter latitude: ")
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n') input, err := reader.ReadString('\n')
if err != nil { if err != nil {
@ -49,10 +48,27 @@ func getPreciseLocation(app *Application) {
app.Config.Latitude = strings.TrimSuffix(input, "\n") app.Config.Latitude = strings.TrimSuffix(input, "\n")
fmt.Print("\nEnter longitude: ") fmt.Print("\nEnter longitude: ")
input, err = reader.ReadString('\n') input, err = reader.ReadString('\n')
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} }
app.Config.Longitude = strings.TrimSuffix(input, "\n") 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)
}
}

View file

@ -31,6 +31,18 @@ type Forecast struct {
Wind Wind `json:"wind"` 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 { type Date struct {
Year int32 Year int32
Month int32 Month int32

View file

@ -21,12 +21,18 @@ func mainMenu(app *Application) {
fmt.Println(" - Added gRPC back end for historical data") fmt.Println(" - Added gRPC back end for historical data")
fmt.Println(" - Option to search historical data added to UI") 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 var option string
// Menu loop
for option != "0" { for option != "0" {
fmt.Print("\nMain Menu\n---------\n\n") fmt.Print("\nMain Menu\n---------\n\n")
fmt.Println("1. Today's forecast (use current location, default)") fmt.Println("1. Use current location (default)")
fmt.Println("2. Advanced options (Change units, precise location, etc.)") fmt.Println("2. Search by zip code")
fmt.Println("3. Search by city")
fmt.Println("4. Advanced options")
fmt.Print("0. Exit\n\n") fmt.Print("0. Exit\n\n")
// Read user input // Read user input
@ -37,18 +43,29 @@ func mainMenu(app *Application) {
} }
option = strings.TrimSuffix(input, "\n") option = strings.TrimSuffix(input, "\n")
// Check user input switch option {
if option == "1" || option == "" { case "":
getLocation(app) getLocation(app)
getCurrent(app) getCurrent(app)
printWeather(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) advancedMenu(app)
} else if option == "0" { case "0":
return return
} else { default:
fmt.Print("\nOops! An error occurred, please choose a valid option.\n\n") fmt.Print("\nOops! An error occurred, please choose a valid option.\n\n")
} }
} }
} }

View file

@ -2,6 +2,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
@ -16,6 +17,32 @@ func getCurrent(app *Application) {
key := "&appid=" + app.Config.ApiKey key := "&appid=" + app.Config.ApiKey
url := "https://pro.openweathermap.org/data/2.5/weather?" + lat + lon + units + key 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) res, err := http.Get(url)
if err != nil { if err != nil {
log.Println(err) log.Println(err)