109 lines
3.0 KiB
Go
109 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/leaktechnologies/skyfeed/internal/config"
|
|
"github.com/leaktechnologies/skyfeed/internal/geo"
|
|
"github.com/leaktechnologies/skyfeed/internal/output"
|
|
"github.com/leaktechnologies/skyfeed/internal/weather"
|
|
)
|
|
|
|
var rootCmd = &cobra.Command{
|
|
Use: "skyfeed",
|
|
Short: "Skyfeed - Open Weather Engine for Telefact and Terminal",
|
|
Long: `Skyfeed fetches and normalizes weather data from Environment Canada,
|
|
using a local IP database for accurate geolocation. It supports both CLI and API modes.`,
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
cmd.Help()
|
|
},
|
|
}
|
|
|
|
func main() {
|
|
// Initialize configuration and ensure data directories exist
|
|
config.Init()
|
|
|
|
// Register subcommands
|
|
rootCmd.AddCommand(fetchCmd)
|
|
rootCmd.AddCommand(showCmd)
|
|
rootCmd.AddCommand(updateCmd)
|
|
|
|
if err := rootCmd.Execute(); err != nil {
|
|
fmt.Println("Error:", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// ------------------------------
|
|
// Subcommands
|
|
// ------------------------------
|
|
|
|
var fetchCmd = &cobra.Command{
|
|
Use: "fetch",
|
|
Short: "Fetch the latest weather data for your current location",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
output.LogInfo("Skyfeed: Checking IP database...")
|
|
if err := geo.EnsureIPDBUpToDate(); err != nil {
|
|
output.LogError(fmt.Sprintf("Failed to update IP DB: %v", err))
|
|
return
|
|
}
|
|
|
|
output.LogInfo("Skyfeed: Detecting location...")
|
|
city, lat, lon, err := geo.GetUserLocation()
|
|
if err != nil {
|
|
output.LogError(fmt.Sprintf("Could not determine location: %v", err))
|
|
return
|
|
}
|
|
output.LogInfo(fmt.Sprintf("Detected: %s (%.4f, %.4f)", city, lat, lon))
|
|
|
|
output.LogInfo("Finding nearest Environment Canada station...")
|
|
station, err := geo.FindNearestStation(lat, lon)
|
|
if err != nil {
|
|
output.LogError(fmt.Sprintf("Station lookup failed: %v", err))
|
|
return
|
|
}
|
|
output.LogInfo(fmt.Sprintf("Nearest station: %s [%s]", station.Name, station.Code))
|
|
|
|
output.LogInfo("Fetching latest weather data...")
|
|
// Determine province from the station (if available)
|
|
province := strings.Split(station.Code, "_")[0] // fallback heuristic
|
|
data, err := weather.FetchCurrent(station.Code, province)
|
|
if err != nil {
|
|
output.LogError(fmt.Sprintf("Weather fetch failed: %v", err))
|
|
return
|
|
}
|
|
|
|
fmt.Println(output.FormatWeatherCLI(data, true))
|
|
},
|
|
}
|
|
|
|
var showCmd = &cobra.Command{
|
|
Use: "show",
|
|
Short: "Show cached weather data from disk",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
data, err := weather.LoadCached()
|
|
if err != nil {
|
|
output.LogError(fmt.Sprintf("Failed to load cache: %v", err))
|
|
return
|
|
}
|
|
fmt.Println(output.FormatWeatherCLI(data, true))
|
|
},
|
|
}
|
|
|
|
var updateCmd = &cobra.Command{
|
|
Use: "update-ipdb",
|
|
Short: "Manually update the local IP geolocation database",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
output.LogInfo("Forcing IP database update...")
|
|
if err := geo.ForceUpdateIPDB(); err != nil {
|
|
output.LogError(fmt.Sprintf("Update failed: %v", err))
|
|
return
|
|
}
|
|
output.LogSuccess("IP database updated successfully.")
|
|
},
|
|
}
|