mirror of
https://codeberg.org/andyscott/weather-cli.git
synced 2024-12-21 12:43:09 -05:00
Reorgainzed menus, added search by zip and city
This commit is contained in:
parent
0143e501db
commit
740af88a2a
6 changed files with 142 additions and 70 deletions
104
cmd/advanced.go
104
cmd/advanced.go
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
12
cmd/main.go
12
cmd/main.go
|
@ -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
|
||||||
|
|
35
cmd/menu.go
35
cmd/menu.go
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue