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.") }, }